diff options
75 files changed, 3252 insertions, 2837 deletions
diff --git a/Documentation/ABI/testing/sysfs-class-uwb_rc b/Documentation/ABI/testing/sysfs-class-uwb_rc index a0d18dbeb7a..6a5fd072849 100644 --- a/Documentation/ABI/testing/sysfs-class-uwb_rc +++ b/Documentation/ABI/testing/sysfs-class-uwb_rc | |||
| @@ -32,14 +32,16 @@ Contact: linux-usb@vger.kernel.org | |||
| 32 | Description: | 32 | Description: |
| 33 | Write: | 33 | Write: |
| 34 | 34 | ||
| 35 | <channel> [<bpst offset>] | 35 | <channel> |
| 36 | 36 | ||
| 37 | to start beaconing on a specific channel, or stop | 37 | to force a specific channel to be used when beaconing, |
| 38 | beaconing if <channel> is -1. Valid channels depends | 38 | or, if <channel> is -1, to prohibit beaconing. If |
| 39 | on the radio controller's supported band groups. | 39 | <channel> is 0, then the default channel selection |
| 40 | algorithm will be used. Valid channels depends on the | ||
| 41 | radio controller's supported band groups. | ||
| 40 | 42 | ||
| 41 | <bpst offset> may be used to try and join a specific | 43 | Reading returns the currently active channel, or -1 if |
| 42 | beacon group if more than one was found during a scan. | 44 | the radio controller is not beaconing. |
| 43 | 45 | ||
| 44 | What: /sys/class/uwb_rc/uwbN/scan | 46 | What: /sys/class/uwb_rc/uwbN/scan |
| 45 | Date: July 2008 | 47 | Date: July 2008 |
diff --git a/Documentation/usb/wusb-cbaf b/Documentation/usb/wusb-cbaf index 2e78b70f3ad..426ddaaef96 100644 --- a/Documentation/usb/wusb-cbaf +++ b/Documentation/usb/wusb-cbaf | |||
| @@ -80,12 +80,6 @@ case $1 in | |||
| 80 | start) | 80 | start) |
| 81 | for dev in ${2:-$hdevs} | 81 | for dev in ${2:-$hdevs} |
| 82 | do | 82 | do |
| 83 | uwb_rc=$(readlink -f $dev/uwb_rc) | ||
| 84 | if cat $uwb_rc/beacon | grep -q -- "-1" | ||
| 85 | then | ||
| 86 | echo 13 0 > $uwb_rc/beacon | ||
| 87 | echo I: started beaconing on ch 13 on $(basename $uwb_rc) >&2 | ||
| 88 | fi | ||
| 89 | echo $host_CHID > $dev/wusb_chid | 83 | echo $host_CHID > $dev/wusb_chid |
| 90 | echo I: started host $(basename $dev) >&2 | 84 | echo I: started host $(basename $dev) >&2 |
| 91 | done | 85 | done |
| @@ -95,9 +89,6 @@ case $1 in | |||
| 95 | do | 89 | do |
| 96 | echo 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > $dev/wusb_chid | 90 | echo 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > $dev/wusb_chid |
| 97 | echo I: stopped host $(basename $dev) >&2 | 91 | echo I: stopped host $(basename $dev) >&2 |
| 98 | uwb_rc=$(readlink -f $dev/uwb_rc) | ||
| 99 | echo -1 | cat > $uwb_rc/beacon | ||
| 100 | echo I: stopped beaconing on $(basename $uwb_rc) >&2 | ||
| 101 | done | 92 | done |
| 102 | ;; | 93 | ;; |
| 103 | set-chid) | 94 | set-chid) |
diff --git a/drivers/usb/host/hwa-hc.c b/drivers/usb/host/hwa-hc.c index 64be4d88df1..8582236e4ca 100644 --- a/drivers/usb/host/hwa-hc.c +++ b/drivers/usb/host/hwa-hc.c | |||
| @@ -54,7 +54,6 @@ | |||
| 54 | * DWA). | 54 | * DWA). |
| 55 | */ | 55 | */ |
| 56 | #include <linux/kernel.h> | 56 | #include <linux/kernel.h> |
| 57 | #include <linux/version.h> | ||
| 58 | #include <linux/init.h> | 57 | #include <linux/init.h> |
| 59 | #include <linux/module.h> | 58 | #include <linux/module.h> |
| 60 | #include <linux/workqueue.h> | 59 | #include <linux/workqueue.h> |
| @@ -63,16 +62,12 @@ | |||
| 63 | #include "../wusbcore/wa-hc.h" | 62 | #include "../wusbcore/wa-hc.h" |
| 64 | #include "../wusbcore/wusbhc.h" | 63 | #include "../wusbcore/wusbhc.h" |
| 65 | 64 | ||
| 66 | #define D_LOCAL 0 | ||
| 67 | #include <linux/uwb/debug.h> | ||
| 68 | |||
| 69 | struct hwahc { | 65 | struct hwahc { |
| 70 | struct wusbhc wusbhc; /* has to be 1st */ | 66 | struct wusbhc wusbhc; /* has to be 1st */ |
| 71 | struct wahc wa; | 67 | struct wahc wa; |
| 72 | u8 buffer[16]; /* for misc usb transactions */ | ||
| 73 | }; | 68 | }; |
| 74 | 69 | ||
| 75 | /** | 70 | /* |
| 76 | * FIXME should be wusbhc | 71 | * FIXME should be wusbhc |
| 77 | * | 72 | * |
| 78 | * NOTE: we need to cache the Cluster ID because later...there is no | 73 | * NOTE: we need to cache the Cluster ID because later...there is no |
| @@ -126,7 +121,6 @@ static int hwahc_op_reset(struct usb_hcd *usb_hcd) | |||
| 126 | struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc); | 121 | struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc); |
| 127 | struct device *dev = &hwahc->wa.usb_iface->dev; | 122 | struct device *dev = &hwahc->wa.usb_iface->dev; |
| 128 | 123 | ||
| 129 | d_fnstart(4, dev, "(hwahc %p)\n", hwahc); | ||
| 130 | mutex_lock(&wusbhc->mutex); | 124 | mutex_lock(&wusbhc->mutex); |
| 131 | wa_nep_disarm(&hwahc->wa); | 125 | wa_nep_disarm(&hwahc->wa); |
| 132 | result = __wa_set_feature(&hwahc->wa, WA_RESET); | 126 | result = __wa_set_feature(&hwahc->wa, WA_RESET); |
| @@ -134,7 +128,6 @@ static int hwahc_op_reset(struct usb_hcd *usb_hcd) | |||
| 134 | dev_err(dev, "error commanding HC to reset: %d\n", result); | 128 | dev_err(dev, "error commanding HC to reset: %d\n", result); |
| 135 | goto error_unlock; | 129 | goto error_unlock; |
| 136 | } | 130 | } |
| 137 | d_printf(3, dev, "reset: waiting for device to change state\n"); | ||
| 138 | result = __wa_wait_status(&hwahc->wa, WA_STATUS_RESETTING, 0); | 131 | result = __wa_wait_status(&hwahc->wa, WA_STATUS_RESETTING, 0); |
| 139 | if (result < 0) { | 132 | if (result < 0) { |
| 140 | dev_err(dev, "error waiting for HC to reset: %d\n", result); | 133 | dev_err(dev, "error waiting for HC to reset: %d\n", result); |
| @@ -142,7 +135,6 @@ static int hwahc_op_reset(struct usb_hcd *usb_hcd) | |||
| 142 | } | 135 | } |
| 143 | error_unlock: | 136 | error_unlock: |
| 144 | mutex_unlock(&wusbhc->mutex); | 137 | mutex_unlock(&wusbhc->mutex); |
| 145 | d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result); | ||
| 146 | return result; | 138 | return result; |
| 147 | } | 139 | } |
| 148 | 140 | ||
| @@ -155,15 +147,9 @@ static int hwahc_op_start(struct usb_hcd *usb_hcd) | |||
| 155 | int result; | 147 | int result; |
| 156 | struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd); | 148 | struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd); |
| 157 | struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc); | 149 | struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc); |
| 158 | struct device *dev = &hwahc->wa.usb_iface->dev; | ||
| 159 | 150 | ||
| 160 | /* Set up a Host Info WUSB Information Element */ | ||
| 161 | d_fnstart(4, dev, "(hwahc %p)\n", hwahc); | ||
| 162 | result = -ENOSPC; | 151 | result = -ENOSPC; |
| 163 | mutex_lock(&wusbhc->mutex); | 152 | mutex_lock(&wusbhc->mutex); |
| 164 | /* Start the numbering from the top so that the bottom | ||
| 165 | * range of the unauth addr space is used for devices, | ||
| 166 | * the top for HCs; use 0xfe - RC# */ | ||
| 167 | addr = wusb_cluster_id_get(); | 153 | addr = wusb_cluster_id_get(); |
| 168 | if (addr == 0) | 154 | if (addr == 0) |
| 169 | goto error_cluster_id_get; | 155 | goto error_cluster_id_get; |
| @@ -171,22 +157,14 @@ static int hwahc_op_start(struct usb_hcd *usb_hcd) | |||
| 171 | if (result < 0) | 157 | if (result < 0) |
| 172 | goto error_set_cluster_id; | 158 | goto error_set_cluster_id; |
| 173 | 159 | ||
| 174 | result = wa_nep_arm(&hwahc->wa, GFP_KERNEL); | ||
| 175 | if (result < 0) { | ||
| 176 | dev_err(dev, "cannot listen to notifications: %d\n", result); | ||
| 177 | goto error_stop; | ||
| 178 | } | ||
| 179 | usb_hcd->uses_new_polling = 1; | 160 | usb_hcd->uses_new_polling = 1; |
| 180 | usb_hcd->poll_rh = 1; | 161 | usb_hcd->poll_rh = 1; |
| 181 | usb_hcd->state = HC_STATE_RUNNING; | 162 | usb_hcd->state = HC_STATE_RUNNING; |
| 182 | result = 0; | 163 | result = 0; |
| 183 | out: | 164 | out: |
| 184 | mutex_unlock(&wusbhc->mutex); | 165 | mutex_unlock(&wusbhc->mutex); |
| 185 | d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result); | ||
| 186 | return result; | 166 | return result; |
| 187 | 167 | ||
| 188 | error_stop: | ||
| 189 | __wa_stop(&hwahc->wa); | ||
| 190 | error_set_cluster_id: | 168 | error_set_cluster_id: |
| 191 | wusb_cluster_id_put(wusbhc->cluster_id); | 169 | wusb_cluster_id_put(wusbhc->cluster_id); |
| 192 | error_cluster_id_get: | 170 | error_cluster_id_get: |
| @@ -194,39 +172,6 @@ error_cluster_id_get: | |||
| 194 | 172 | ||
| 195 | } | 173 | } |
| 196 | 174 | ||
| 197 | /* | ||
| 198 | * FIXME: break this function up | ||
| 199 | */ | ||
| 200 | static int __hwahc_op_wusbhc_start(struct wusbhc *wusbhc) | ||
| 201 | { | ||
| 202 | int result; | ||
| 203 | struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc); | ||
| 204 | struct device *dev = &hwahc->wa.usb_iface->dev; | ||
| 205 | |||
| 206 | /* Set up a Host Info WUSB Information Element */ | ||
| 207 | d_fnstart(4, dev, "(hwahc %p)\n", hwahc); | ||
| 208 | result = -ENOSPC; | ||
| 209 | |||
| 210 | result = __wa_set_feature(&hwahc->wa, WA_ENABLE); | ||
| 211 | if (result < 0) { | ||
| 212 | dev_err(dev, "error commanding HC to start: %d\n", result); | ||
| 213 | goto error_stop; | ||
| 214 | } | ||
| 215 | result = __wa_wait_status(&hwahc->wa, WA_ENABLE, WA_ENABLE); | ||
| 216 | if (result < 0) { | ||
| 217 | dev_err(dev, "error waiting for HC to start: %d\n", result); | ||
| 218 | goto error_stop; | ||
| 219 | } | ||
| 220 | result = 0; | ||
| 221 | out: | ||
| 222 | d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result); | ||
| 223 | return result; | ||
| 224 | |||
| 225 | error_stop: | ||
| 226 | result = __wa_clear_feature(&hwahc->wa, WA_ENABLE); | ||
| 227 | goto out; | ||
| 228 | } | ||
| 229 | |||
| 230 | static int hwahc_op_suspend(struct usb_hcd *usb_hcd, pm_message_t msg) | 175 | static int hwahc_op_suspend(struct usb_hcd *usb_hcd, pm_message_t msg) |
| 231 | { | 176 | { |
| 232 | struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd); | 177 | struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd); |
| @@ -246,18 +191,6 @@ static int hwahc_op_resume(struct usb_hcd *usb_hcd) | |||
| 246 | return -ENOSYS; | 191 | return -ENOSYS; |
| 247 | } | 192 | } |
| 248 | 193 | ||
| 249 | static void __hwahc_op_wusbhc_stop(struct wusbhc *wusbhc) | ||
| 250 | { | ||
| 251 | int result; | ||
| 252 | struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc); | ||
| 253 | struct device *dev = &hwahc->wa.usb_iface->dev; | ||
| 254 | |||
| 255 | d_fnstart(4, dev, "(hwahc %p)\n", hwahc); | ||
| 256 | /* Nothing for now */ | ||
| 257 | d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result); | ||
| 258 | return; | ||
| 259 | } | ||
| 260 | |||
| 261 | /* | 194 | /* |
| 262 | * No need to abort pipes, as when this is called, all the children | 195 | * No need to abort pipes, as when this is called, all the children |
| 263 | * has been disconnected and that has done it [through | 196 | * has been disconnected and that has done it [through |
| @@ -266,21 +199,11 @@ static void __hwahc_op_wusbhc_stop(struct wusbhc *wusbhc) | |||
| 266 | */ | 199 | */ |
| 267 | static void hwahc_op_stop(struct usb_hcd *usb_hcd) | 200 | static void hwahc_op_stop(struct usb_hcd *usb_hcd) |
| 268 | { | 201 | { |
| 269 | int result; | ||
| 270 | struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd); | 202 | struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd); |
| 271 | struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc); | ||
| 272 | struct wahc *wa = &hwahc->wa; | ||
| 273 | struct device *dev = &wa->usb_iface->dev; | ||
| 274 | 203 | ||
| 275 | d_fnstart(4, dev, "(hwahc %p)\n", hwahc); | ||
| 276 | mutex_lock(&wusbhc->mutex); | 204 | mutex_lock(&wusbhc->mutex); |
| 277 | wusbhc_stop(wusbhc); | ||
| 278 | wa_nep_disarm(&hwahc->wa); | ||
| 279 | result = __wa_stop(&hwahc->wa); | ||
| 280 | wusb_cluster_id_put(wusbhc->cluster_id); | 205 | wusb_cluster_id_put(wusbhc->cluster_id); |
| 281 | mutex_unlock(&wusbhc->mutex); | 206 | mutex_unlock(&wusbhc->mutex); |
| 282 | d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result); | ||
| 283 | return; | ||
| 284 | } | 207 | } |
| 285 | 208 | ||
| 286 | static int hwahc_op_get_frame_number(struct usb_hcd *usb_hcd) | 209 | static int hwahc_op_get_frame_number(struct usb_hcd *usb_hcd) |
| @@ -325,6 +248,54 @@ static void hwahc_op_endpoint_disable(struct usb_hcd *usb_hcd, | |||
| 325 | rpipe_ep_disable(&hwahc->wa, ep); | 248 | rpipe_ep_disable(&hwahc->wa, ep); |
| 326 | } | 249 | } |
| 327 | 250 | ||
| 251 | static int __hwahc_op_wusbhc_start(struct wusbhc *wusbhc) | ||
| 252 | { | ||
| 253 | int result; | ||
| 254 | struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc); | ||
| 255 | struct device *dev = &hwahc->wa.usb_iface->dev; | ||
| 256 | |||
| 257 | result = __wa_set_feature(&hwahc->wa, WA_ENABLE); | ||
| 258 | if (result < 0) { | ||
| 259 | dev_err(dev, "error commanding HC to start: %d\n", result); | ||
| 260 | goto error_stop; | ||
| 261 | } | ||
| 262 | result = __wa_wait_status(&hwahc->wa, WA_ENABLE, WA_ENABLE); | ||
| 263 | if (result < 0) { | ||
| 264 | dev_err(dev, "error waiting for HC to start: %d\n", result); | ||
| 265 | goto error_stop; | ||
| 266 | } | ||
| 267 | result = wa_nep_arm(&hwahc->wa, GFP_KERNEL); | ||
| 268 | if (result < 0) { | ||
| 269 | dev_err(dev, "cannot listen to notifications: %d\n", result); | ||
| 270 | goto error_stop; | ||
| 271 | } | ||
| 272 | return result; | ||
| 273 | |||
| 274 | error_stop: | ||
| 275 | __wa_clear_feature(&hwahc->wa, WA_ENABLE); | ||
| 276 | return result; | ||
| 277 | } | ||
| 278 | |||
| 279 | static void __hwahc_op_wusbhc_stop(struct wusbhc *wusbhc, int delay) | ||
| 280 | { | ||
| 281 | struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc); | ||
| 282 | struct wahc *wa = &hwahc->wa; | ||
| 283 | u8 iface_no = wa->usb_iface->cur_altsetting->desc.bInterfaceNumber; | ||
| 284 | int ret; | ||
| 285 | |||
| 286 | ret = usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0), | ||
| 287 | WUSB_REQ_CHAN_STOP, | ||
| 288 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | ||
| 289 | delay * 1000, | ||
| 290 | iface_no, | ||
| 291 | NULL, 0, 1000 /* FIXME: arbitrary */); | ||
| 292 | if (ret == 0) | ||
| 293 | msleep(delay); | ||
| 294 | |||
| 295 | wa_nep_disarm(&hwahc->wa); | ||
| 296 | __wa_stop(&hwahc->wa); | ||
| 297 | } | ||
| 298 | |||
| 328 | /* | 299 | /* |
| 329 | * Set the UWB MAS allocation for the WUSB cluster | 300 | * Set the UWB MAS allocation for the WUSB cluster |
| 330 | * | 301 | * |
| @@ -581,11 +552,11 @@ static int wa_fill_descr(struct wahc *wa) | |||
| 581 | itr_size = le16_to_cpu(usb_dev->actconfig->desc.wTotalLength); | 552 | itr_size = le16_to_cpu(usb_dev->actconfig->desc.wTotalLength); |
| 582 | while (itr_size >= sizeof(*hdr)) { | 553 | while (itr_size >= sizeof(*hdr)) { |
| 583 | hdr = (struct usb_descriptor_header *) itr; | 554 | hdr = (struct usb_descriptor_header *) itr; |
| 584 | d_printf(3, dev, "Extra device descriptor: " | 555 | dev_dbg(dev, "Extra device descriptor: " |
| 585 | "type %02x/%u bytes @ %zu (%zu left)\n", | 556 | "type %02x/%u bytes @ %zu (%zu left)\n", |
| 586 | hdr->bDescriptorType, hdr->bLength, | 557 | hdr->bDescriptorType, hdr->bLength, |
| 587 | (itr - usb_dev->rawdescriptors[actconfig_idx]), | 558 | (itr - usb_dev->rawdescriptors[actconfig_idx]), |
| 588 | itr_size); | 559 | itr_size); |
| 589 | if (hdr->bDescriptorType == USB_DT_WIRE_ADAPTER) | 560 | if (hdr->bDescriptorType == USB_DT_WIRE_ADAPTER) |
| 590 | goto found; | 561 | goto found; |
| 591 | itr += hdr->bLength; | 562 | itr += hdr->bLength; |
| @@ -794,7 +765,6 @@ static void hwahc_destroy(struct hwahc *hwahc) | |||
| 794 | { | 765 | { |
| 795 | struct wusbhc *wusbhc = &hwahc->wusbhc; | 766 | struct wusbhc *wusbhc = &hwahc->wusbhc; |
| 796 | 767 | ||
| 797 | d_fnstart(1, NULL, "(hwahc %p)\n", hwahc); | ||
| 798 | mutex_lock(&wusbhc->mutex); | 768 | mutex_lock(&wusbhc->mutex); |
| 799 | __wa_destroy(&hwahc->wa); | 769 | __wa_destroy(&hwahc->wa); |
| 800 | wusbhc_destroy(&hwahc->wusbhc); | 770 | wusbhc_destroy(&hwahc->wusbhc); |
| @@ -804,7 +774,6 @@ static void hwahc_destroy(struct hwahc *hwahc) | |||
| 804 | usb_put_intf(hwahc->wa.usb_iface); | 774 | usb_put_intf(hwahc->wa.usb_iface); |
| 805 | usb_put_dev(hwahc->wa.usb_dev); | 775 | usb_put_dev(hwahc->wa.usb_dev); |
| 806 | mutex_unlock(&wusbhc->mutex); | 776 | mutex_unlock(&wusbhc->mutex); |
| 807 | d_fnend(1, NULL, "(hwahc %p) = void\n", hwahc); | ||
| 808 | } | 777 | } |
| 809 | 778 | ||
| 810 | static void hwahc_init(struct hwahc *hwahc) | 779 | static void hwahc_init(struct hwahc *hwahc) |
| @@ -821,7 +790,6 @@ static int hwahc_probe(struct usb_interface *usb_iface, | |||
| 821 | struct hwahc *hwahc; | 790 | struct hwahc *hwahc; |
| 822 | struct device *dev = &usb_iface->dev; | 791 | struct device *dev = &usb_iface->dev; |
| 823 | 792 | ||
| 824 | d_fnstart(4, dev, "(%p, %p)\n", usb_iface, id); | ||
| 825 | result = -ENOMEM; | 793 | result = -ENOMEM; |
| 826 | usb_hcd = usb_create_hcd(&hwahc_hc_driver, &usb_iface->dev, "wusb-hwa"); | 794 | usb_hcd = usb_create_hcd(&hwahc_hc_driver, &usb_iface->dev, "wusb-hwa"); |
| 827 | if (usb_hcd == NULL) { | 795 | if (usb_hcd == NULL) { |
| @@ -848,7 +816,6 @@ static int hwahc_probe(struct usb_interface *usb_iface, | |||
| 848 | dev_err(dev, "Cannot setup phase B of WUSBHC: %d\n", result); | 816 | dev_err(dev, "Cannot setup phase B of WUSBHC: %d\n", result); |
| 849 | goto error_wusbhc_b_create; | 817 | goto error_wusbhc_b_create; |
| 850 | } | 818 | } |
| 851 | d_fnend(4, dev, "(%p, %p) = 0\n", usb_iface, id); | ||
| 852 | return 0; | 819 | return 0; |
| 853 | 820 | ||
| 854 | error_wusbhc_b_create: | 821 | error_wusbhc_b_create: |
| @@ -858,7 +825,6 @@ error_add_hcd: | |||
| 858 | error_hwahc_create: | 825 | error_hwahc_create: |
| 859 | usb_put_hcd(usb_hcd); | 826 | usb_put_hcd(usb_hcd); |
| 860 | error_alloc: | 827 | error_alloc: |
| 861 | d_fnend(4, dev, "(%p, %p) = %d\n", usb_iface, id, result); | ||
| 862 | return result; | 828 | return result; |
| 863 | } | 829 | } |
| 864 | 830 | ||
| @@ -872,16 +838,12 @@ static void hwahc_disconnect(struct usb_interface *usb_iface) | |||
| 872 | wusbhc = usb_hcd_to_wusbhc(usb_hcd); | 838 | wusbhc = usb_hcd_to_wusbhc(usb_hcd); |
| 873 | hwahc = container_of(wusbhc, struct hwahc, wusbhc); | 839 | hwahc = container_of(wusbhc, struct hwahc, wusbhc); |
| 874 | 840 | ||
| 875 | d_fnstart(1, NULL, "(hwahc %p [usb_iface %p])\n", hwahc, usb_iface); | ||
| 876 | wusbhc_b_destroy(&hwahc->wusbhc); | 841 | wusbhc_b_destroy(&hwahc->wusbhc); |
| 877 | usb_remove_hcd(usb_hcd); | 842 | usb_remove_hcd(usb_hcd); |
| 878 | hwahc_destroy(hwahc); | 843 | hwahc_destroy(hwahc); |
| 879 | usb_put_hcd(usb_hcd); | 844 | usb_put_hcd(usb_hcd); |
| 880 | d_fnend(1, NULL, "(hwahc %p [usb_iface %p]) = void\n", hwahc, | ||
| 881 | usb_iface); | ||
| 882 | } | 845 | } |
| 883 | 846 | ||
| 884 | /** USB device ID's that we handle */ | ||
| 885 | static struct usb_device_id hwahc_id_table[] = { | 847 | static struct usb_device_id hwahc_id_table[] = { |
| 886 | /* FIXME: use class labels for this */ | 848 | /* FIXME: use class labels for this */ |
| 887 | { USB_INTERFACE_INFO(0xe0, 0x02, 0x01), }, | 849 | { USB_INTERFACE_INFO(0xe0, 0x02, 0x01), }, |
| @@ -898,18 +860,7 @@ static struct usb_driver hwahc_driver = { | |||
| 898 | 860 | ||
| 899 | static int __init hwahc_driver_init(void) | 861 | static int __init hwahc_driver_init(void) |
| 900 | { | 862 | { |
| 901 | int result; | 863 | return usb_register(&hwahc_driver); |
| 902 | result = usb_register(&hwahc_driver); | ||
| 903 | if (result < 0) { | ||
| 904 | printk(KERN_ERR "WA-CDS: Cannot register USB driver: %d\n", | ||
| 905 | result); | ||
| 906 | goto error_usb_register; | ||
| 907 | } | ||
| 908 | return 0; | ||
| 909 | |||
| 910 | error_usb_register: | ||
| 911 | return result; | ||
| 912 | |||
| 913 | } | 864 | } |
| 914 | module_init(hwahc_driver_init); | 865 | module_init(hwahc_driver_init); |
| 915 | 866 | ||
diff --git a/drivers/usb/host/whci/Kbuild b/drivers/usb/host/whci/Kbuild index 26a3871ea0f..11e5040b833 100644 --- a/drivers/usb/host/whci/Kbuild +++ b/drivers/usb/host/whci/Kbuild | |||
| @@ -2,6 +2,7 @@ obj-$(CONFIG_USB_WHCI_HCD) += whci-hcd.o | |||
| 2 | 2 | ||
| 3 | whci-hcd-y := \ | 3 | whci-hcd-y := \ |
| 4 | asl.o \ | 4 | asl.o \ |
| 5 | debug.o \ | ||
| 5 | hcd.o \ | 6 | hcd.o \ |
| 6 | hw.o \ | 7 | hw.o \ |
| 7 | init.o \ | 8 | init.o \ |
diff --git a/drivers/usb/host/whci/asl.c b/drivers/usb/host/whci/asl.c index 4d7078e5057..577c0d29849 100644 --- a/drivers/usb/host/whci/asl.c +++ b/drivers/usb/host/whci/asl.c | |||
| @@ -19,32 +19,11 @@ | |||
| 19 | #include <linux/dma-mapping.h> | 19 | #include <linux/dma-mapping.h> |
| 20 | #include <linux/uwb/umc.h> | 20 | #include <linux/uwb/umc.h> |
| 21 | #include <linux/usb.h> | 21 | #include <linux/usb.h> |
| 22 | #define D_LOCAL 0 | ||
| 23 | #include <linux/uwb/debug.h> | ||
| 24 | 22 | ||
| 25 | #include "../../wusbcore/wusbhc.h" | 23 | #include "../../wusbcore/wusbhc.h" |
| 26 | 24 | ||
| 27 | #include "whcd.h" | 25 | #include "whcd.h" |
| 28 | 26 | ||
| 29 | #if D_LOCAL >= 4 | ||
| 30 | static void dump_asl(struct whc *whc, const char *tag) | ||
| 31 | { | ||
| 32 | struct device *dev = &whc->umc->dev; | ||
| 33 | struct whc_qset *qset; | ||
| 34 | |||
| 35 | d_printf(4, dev, "ASL %s\n", tag); | ||
| 36 | |||
| 37 | list_for_each_entry(qset, &whc->async_list, list_node) { | ||
| 38 | dump_qset(qset, dev); | ||
| 39 | } | ||
| 40 | } | ||
| 41 | #else | ||
| 42 | static inline void dump_asl(struct whc *whc, const char *tag) | ||
| 43 | { | ||
| 44 | } | ||
| 45 | #endif | ||
| 46 | |||
| 47 | |||
| 48 | static void qset_get_next_prev(struct whc *whc, struct whc_qset *qset, | 27 | static void qset_get_next_prev(struct whc *whc, struct whc_qset *qset, |
| 49 | struct whc_qset **next, struct whc_qset **prev) | 28 | struct whc_qset **next, struct whc_qset **prev) |
| 50 | { | 29 | { |
| @@ -179,11 +158,26 @@ void asl_stop(struct whc *whc) | |||
| 179 | 1000, "stop ASL"); | 158 | 1000, "stop ASL"); |
| 180 | } | 159 | } |
| 181 | 160 | ||
| 161 | /** | ||
| 162 | * asl_update - request an ASL update and wait for the hardware to be synced | ||
| 163 | * @whc: the WHCI HC | ||
| 164 | * @wusbcmd: WUSBCMD value to start the update. | ||
| 165 | * | ||
| 166 | * If the WUSB HC is inactive (i.e., the ASL is stopped) then the | ||
| 167 | * update must be skipped as the hardware may not respond to update | ||
| 168 | * requests. | ||
| 169 | */ | ||
| 182 | void asl_update(struct whc *whc, uint32_t wusbcmd) | 170 | void asl_update(struct whc *whc, uint32_t wusbcmd) |
| 183 | { | 171 | { |
| 184 | whc_write_wusbcmd(whc, wusbcmd, wusbcmd); | 172 | struct wusbhc *wusbhc = &whc->wusbhc; |
| 185 | wait_event(whc->async_list_wq, | 173 | |
| 186 | (le_readl(whc->base + WUSBCMD) & WUSBCMD_ASYNC_UPDATED) == 0); | 174 | mutex_lock(&wusbhc->mutex); |
| 175 | if (wusbhc->active) { | ||
| 176 | whc_write_wusbcmd(whc, wusbcmd, wusbcmd); | ||
| 177 | wait_event(whc->async_list_wq, | ||
| 178 | (le_readl(whc->base + WUSBCMD) & WUSBCMD_ASYNC_UPDATED) == 0); | ||
| 179 | } | ||
| 180 | mutex_unlock(&wusbhc->mutex); | ||
| 187 | } | 181 | } |
| 188 | 182 | ||
| 189 | /** | 183 | /** |
| @@ -202,8 +196,6 @@ void scan_async_work(struct work_struct *work) | |||
| 202 | 196 | ||
| 203 | spin_lock_irq(&whc->lock); | 197 | spin_lock_irq(&whc->lock); |
| 204 | 198 | ||
| 205 | dump_asl(whc, "before processing"); | ||
| 206 | |||
| 207 | /* | 199 | /* |
| 208 | * Transerve the software list backwards so new qsets can be | 200 | * Transerve the software list backwards so new qsets can be |
| 209 | * safely inserted into the ASL without making it non-circular. | 201 | * safely inserted into the ASL without making it non-circular. |
| @@ -217,8 +209,6 @@ void scan_async_work(struct work_struct *work) | |||
| 217 | update |= process_qset(whc, qset); | 209 | update |= process_qset(whc, qset); |
| 218 | } | 210 | } |
| 219 | 211 | ||
| 220 | dump_asl(whc, "after processing"); | ||
| 221 | |||
| 222 | spin_unlock_irq(&whc->lock); | 212 | spin_unlock_irq(&whc->lock); |
| 223 | 213 | ||
| 224 | if (update) { | 214 | if (update) { |
diff --git a/drivers/usb/host/whci/debug.c b/drivers/usb/host/whci/debug.c new file mode 100644 index 00000000000..cf2d45946c5 --- /dev/null +++ b/drivers/usb/host/whci/debug.c | |||
| @@ -0,0 +1,189 @@ | |||
| 1 | /* | ||
| 2 | * Wireless Host Controller (WHC) debug. | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008 Cambridge Silicon Radio Ltd. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public License version | ||
| 8 | * 2 as published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 17 | */ | ||
| 18 | #include <linux/kernel.h> | ||
| 19 | #include <linux/debugfs.h> | ||
| 20 | #include <linux/seq_file.h> | ||
| 21 | |||
| 22 | #include "../../wusbcore/wusbhc.h" | ||
| 23 | |||
| 24 | #include "whcd.h" | ||
| 25 | |||
| 26 | struct whc_dbg { | ||
| 27 | struct dentry *di_f; | ||
| 28 | struct dentry *asl_f; | ||
| 29 | struct dentry *pzl_f; | ||
| 30 | }; | ||
| 31 | |||
| 32 | void qset_print(struct seq_file *s, struct whc_qset *qset) | ||
| 33 | { | ||
| 34 | struct whc_std *std; | ||
| 35 | struct urb *urb = NULL; | ||
| 36 | int i; | ||
| 37 | |||
| 38 | seq_printf(s, "qset %08x\n", (u32)qset->qset_dma); | ||
| 39 | seq_printf(s, " -> %08x\n", (u32)qset->qh.link); | ||
| 40 | seq_printf(s, " info: %08x %08x %08x\n", | ||
| 41 | qset->qh.info1, qset->qh.info2, qset->qh.info3); | ||
| 42 | seq_printf(s, " sts: %04x errs: %d\n", qset->qh.status, qset->qh.err_count); | ||
| 43 | seq_printf(s, " TD: sts: %08x opts: %08x\n", | ||
| 44 | qset->qh.overlay.qtd.status, qset->qh.overlay.qtd.options); | ||
| 45 | |||
| 46 | for (i = 0; i < WHCI_QSET_TD_MAX; i++) { | ||
| 47 | seq_printf(s, " %c%c TD[%d]: sts: %08x opts: %08x ptr: %08x\n", | ||
| 48 | i == qset->td_start ? 'S' : ' ', | ||
| 49 | i == qset->td_end ? 'E' : ' ', | ||
| 50 | i, qset->qtd[i].status, qset->qtd[i].options, | ||
| 51 | (u32)qset->qtd[i].page_list_ptr); | ||
| 52 | } | ||
| 53 | seq_printf(s, " ntds: %d\n", qset->ntds); | ||
| 54 | list_for_each_entry(std, &qset->stds, list_node) { | ||
| 55 | if (urb != std->urb) { | ||
| 56 | urb = std->urb; | ||
| 57 | seq_printf(s, " urb %p transferred: %d bytes\n", urb, | ||
| 58 | urb->actual_length); | ||
| 59 | } | ||
| 60 | if (std->qtd) | ||
| 61 | seq_printf(s, " sTD[%td]: %zu bytes @ %08x\n", | ||
| 62 | std->qtd - &qset->qtd[0], | ||
| 63 | std->len, std->num_pointers ? | ||
| 64 | (u32)(std->pl_virt[0].buf_ptr) : (u32)std->dma_addr); | ||
| 65 | else | ||
| 66 | seq_printf(s, " sTD[-]: %zd bytes @ %08x\n", | ||
| 67 | std->len, std->num_pointers ? | ||
| 68 | (u32)(std->pl_virt[0].buf_ptr) : (u32)std->dma_addr); | ||
| 69 | } | ||
| 70 | } | ||
| 71 | |||
| 72 | static int di_print(struct seq_file *s, void *p) | ||
| 73 | { | ||
| 74 | struct whc *whc = s->private; | ||
| 75 | char buf[72]; | ||
| 76 | int d; | ||
| 77 | |||
| 78 | for (d = 0; d < whc->n_devices; d++) { | ||
| 79 | struct di_buf_entry *di = &whc->di_buf[d]; | ||
| 80 | |||
| 81 | bitmap_scnprintf(buf, sizeof(buf), | ||
| 82 | (unsigned long *)di->availability_info, UWB_NUM_MAS); | ||
| 83 | |||
| 84 | seq_printf(s, "DI[%d]\n", d); | ||
| 85 | seq_printf(s, " availability: %s\n", buf); | ||
| 86 | seq_printf(s, " %c%c key idx: %d dev addr: %d\n", | ||
| 87 | (di->addr_sec_info & WHC_DI_SECURE) ? 'S' : ' ', | ||
| 88 | (di->addr_sec_info & WHC_DI_DISABLE) ? 'D' : ' ', | ||
| 89 | (di->addr_sec_info & WHC_DI_KEY_IDX_MASK) >> 8, | ||
| 90 | (di->addr_sec_info & WHC_DI_DEV_ADDR_MASK)); | ||
| 91 | } | ||
| 92 | return 0; | ||
| 93 | } | ||
| 94 | |||
| 95 | static int asl_print(struct seq_file *s, void *p) | ||
| 96 | { | ||
| 97 | struct whc *whc = s->private; | ||
| 98 | struct whc_qset *qset; | ||
| 99 | |||
| 100 | list_for_each_entry(qset, &whc->async_list, list_node) { | ||
| 101 | qset_print(s, qset); | ||
| 102 | } | ||
| 103 | |||
| 104 | return 0; | ||
| 105 | } | ||
| 106 | |||
| 107 | static int pzl_print(struct seq_file *s, void *p) | ||
| 108 | { | ||
| 109 | struct whc *whc = s->private; | ||
| 110 | struct whc_qset *qset; | ||
| 111 | int period; | ||
| 112 | |||
| 113 | for (period = 0; period < 5; period++) { | ||
| 114 | seq_printf(s, "Period %d\n", period); | ||
| 115 | list_for_each_entry(qset, &whc->periodic_list[period], list_node) { | ||
| 116 | qset_print(s, qset); | ||
| 117 | } | ||
| 118 | } | ||
| 119 | return 0; | ||
| 120 | } | ||
| 121 | |||
| 122 | static int di_open(struct inode *inode, struct file *file) | ||
| 123 | { | ||
| 124 | return single_open(file, di_print, inode->i_private); | ||
| 125 | } | ||
| 126 | |||
| 127 | static int asl_open(struct inode *inode, struct file *file) | ||
| 128 | { | ||
| 129 | return single_open(file, asl_print, inode->i_private); | ||
| 130 | } | ||
| 131 | |||
| 132 | static int pzl_open(struct inode *inode, struct file *file) | ||
| 133 | { | ||
| 134 | return single_open(file, pzl_print, inode->i_private); | ||
| 135 | } | ||
| 136 | |||
| 137 | static struct file_operations di_fops = { | ||
| 138 | .open = di_open, | ||
| 139 | .read = seq_read, | ||
| 140 | .llseek = seq_lseek, | ||
| 141 | .release = single_release, | ||
| 142 | .owner = THIS_MODULE, | ||
| 143 | }; | ||
| 144 | |||
| 145 | static struct file_operations asl_fops = { | ||
| 146 | .open = asl_open, | ||
| 147 | .read = seq_read, | ||
| 148 | .llseek = seq_lseek, | ||
| 149 | .release = single_release, | ||
| 150 | .owner = THIS_MODULE, | ||
| 151 | }; | ||
| 152 | |||
| 153 | static struct file_operations pzl_fops = { | ||
| 154 | .open = pzl_open, | ||
| 155 | .read = seq_read, | ||
| 156 | .llseek = seq_lseek, | ||
| 157 | .release = single_release, | ||
| 158 | .owner = THIS_MODULE, | ||
| 159 | }; | ||
| 160 | |||
| 161 | void whc_dbg_init(struct whc *whc) | ||
| 162 | { | ||
| 163 | if (whc->wusbhc.pal.debugfs_dir == NULL) | ||
| 164 | return; | ||
| 165 | |||
| 166 | whc->dbg = kzalloc(sizeof(struct whc_dbg), GFP_KERNEL); | ||
| 167 | if (whc->dbg == NULL) | ||
| 168 | return; | ||
| 169 | |||
| 170 | whc->dbg->di_f = debugfs_create_file("di", 0444, | ||
| 171 | whc->wusbhc.pal.debugfs_dir, whc, | ||
| 172 | &di_fops); | ||
| 173 | whc->dbg->asl_f = debugfs_create_file("asl", 0444, | ||
| 174 | whc->wusbhc.pal.debugfs_dir, whc, | ||
| 175 | &asl_fops); | ||
| 176 | whc->dbg->pzl_f = debugfs_create_file("pzl", 0444, | ||
| 177 | whc->wusbhc.pal.debugfs_dir, whc, | ||
| 178 | &pzl_fops); | ||
| 179 | } | ||
| 180 | |||
| 181 | void whc_dbg_clean_up(struct whc *whc) | ||
| 182 | { | ||
| 183 | if (whc->dbg) { | ||
| 184 | debugfs_remove(whc->dbg->pzl_f); | ||
| 185 | debugfs_remove(whc->dbg->asl_f); | ||
| 186 | debugfs_remove(whc->dbg->di_f); | ||
| 187 | kfree(whc->dbg); | ||
| 188 | } | ||
| 189 | } | ||
diff --git a/drivers/usb/host/whci/hcd.c b/drivers/usb/host/whci/hcd.c index ef3ad4dca94..1569afd6245 100644 --- a/drivers/usb/host/whci/hcd.c +++ b/drivers/usb/host/whci/hcd.c | |||
| @@ -15,7 +15,6 @@ | |||
| 15 | * You should have received a copy of the GNU General Public License | 15 | * You should have received a copy of the GNU General Public License |
| 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 17 | */ | 17 | */ |
| 18 | #include <linux/version.h> | ||
| 19 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
| 20 | #include <linux/init.h> | 19 | #include <linux/init.h> |
| 21 | #include <linux/uwb/umc.h> | 20 | #include <linux/uwb/umc.h> |
| @@ -92,8 +91,6 @@ static void whc_stop(struct usb_hcd *usb_hcd) | |||
| 92 | 91 | ||
| 93 | mutex_lock(&wusbhc->mutex); | 92 | mutex_lock(&wusbhc->mutex); |
| 94 | 93 | ||
| 95 | wusbhc_stop(wusbhc); | ||
| 96 | |||
| 97 | /* stop HC */ | 94 | /* stop HC */ |
| 98 | le_writel(0, whc->base + WUSBINTR); | 95 | le_writel(0, whc->base + WUSBINTR); |
| 99 | whc_write_wusbcmd(whc, WUSBCMD_RUN, 0); | 96 | whc_write_wusbcmd(whc, WUSBCMD_RUN, 0); |
| @@ -276,6 +273,8 @@ static int whc_probe(struct umc_dev *umc) | |||
| 276 | goto error_wusbhc_b_create; | 273 | goto error_wusbhc_b_create; |
| 277 | } | 274 | } |
| 278 | 275 | ||
| 276 | whc_dbg_init(whc); | ||
| 277 | |||
| 279 | return 0; | 278 | return 0; |
| 280 | 279 | ||
| 281 | error_wusbhc_b_create: | 280 | error_wusbhc_b_create: |
| @@ -299,6 +298,7 @@ static void whc_remove(struct umc_dev *umc) | |||
| 299 | struct whc *whc = wusbhc_to_whc(wusbhc); | 298 | struct whc *whc = wusbhc_to_whc(wusbhc); |
| 300 | 299 | ||
| 301 | if (usb_hcd) { | 300 | if (usb_hcd) { |
| 301 | whc_dbg_clean_up(whc); | ||
| 302 | wusbhc_b_destroy(wusbhc); | 302 | wusbhc_b_destroy(wusbhc); |
| 303 | usb_remove_hcd(usb_hcd); | 303 | usb_remove_hcd(usb_hcd); |
| 304 | wusbhc_destroy(wusbhc); | 304 | wusbhc_destroy(wusbhc); |
diff --git a/drivers/usb/host/whci/hw.c b/drivers/usb/host/whci/hw.c index ac86e59c122..d498e720321 100644 --- a/drivers/usb/host/whci/hw.c +++ b/drivers/usb/host/whci/hw.c | |||
| @@ -50,6 +50,7 @@ int whc_do_gencmd(struct whc *whc, u32 cmd, u32 params, void *addr, size_t len) | |||
| 50 | unsigned long flags; | 50 | unsigned long flags; |
| 51 | dma_addr_t dma_addr; | 51 | dma_addr_t dma_addr; |
| 52 | int t; | 52 | int t; |
| 53 | int ret = 0; | ||
| 53 | 54 | ||
| 54 | mutex_lock(&whc->mutex); | 55 | mutex_lock(&whc->mutex); |
| 55 | 56 | ||
| @@ -61,7 +62,8 @@ int whc_do_gencmd(struct whc *whc, u32 cmd, u32 params, void *addr, size_t len) | |||
| 61 | dev_err(&whc->umc->dev, "generic command timeout (%04x/%04x)\n", | 62 | dev_err(&whc->umc->dev, "generic command timeout (%04x/%04x)\n", |
| 62 | le_readl(whc->base + WUSBGENCMDSTS), | 63 | le_readl(whc->base + WUSBGENCMDSTS), |
| 63 | le_readl(whc->base + WUSBGENCMDPARAMS)); | 64 | le_readl(whc->base + WUSBGENCMDPARAMS)); |
| 64 | return -ETIMEDOUT; | 65 | ret = -ETIMEDOUT; |
| 66 | goto out; | ||
| 65 | } | 67 | } |
| 66 | 68 | ||
| 67 | if (addr) { | 69 | if (addr) { |
| @@ -80,8 +82,8 @@ int whc_do_gencmd(struct whc *whc, u32 cmd, u32 params, void *addr, size_t len) | |||
| 80 | whc->base + WUSBGENCMDSTS); | 82 | whc->base + WUSBGENCMDSTS); |
| 81 | 83 | ||
| 82 | spin_unlock_irqrestore(&whc->lock, flags); | 84 | spin_unlock_irqrestore(&whc->lock, flags); |
| 83 | 85 | out: | |
| 84 | mutex_unlock(&whc->mutex); | 86 | mutex_unlock(&whc->mutex); |
| 85 | 87 | ||
| 86 | return 0; | 88 | return ret; |
| 87 | } | 89 | } |
diff --git a/drivers/usb/host/whci/int.c b/drivers/usb/host/whci/int.c index fce01174aa9..6aae7002810 100644 --- a/drivers/usb/host/whci/int.c +++ b/drivers/usb/host/whci/int.c | |||
| @@ -15,7 +15,6 @@ | |||
| 15 | * You should have received a copy of the GNU General Public License | 15 | * You should have received a copy of the GNU General Public License |
| 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 17 | */ | 17 | */ |
| 18 | #include <linux/version.h> | ||
| 19 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
| 20 | #include <linux/init.h> | 19 | #include <linux/init.h> |
| 21 | #include <linux/uwb/umc.h> | 20 | #include <linux/uwb/umc.h> |
diff --git a/drivers/usb/host/whci/pzl.c b/drivers/usb/host/whci/pzl.c index 8d62df0c330..2ae5abf69a6 100644 --- a/drivers/usb/host/whci/pzl.c +++ b/drivers/usb/host/whci/pzl.c | |||
| @@ -19,35 +19,11 @@ | |||
| 19 | #include <linux/dma-mapping.h> | 19 | #include <linux/dma-mapping.h> |
| 20 | #include <linux/uwb/umc.h> | 20 | #include <linux/uwb/umc.h> |
| 21 | #include <linux/usb.h> | 21 | #include <linux/usb.h> |
| 22 | #define D_LOCAL 0 | ||
| 23 | #include <linux/uwb/debug.h> | ||
| 24 | 22 | ||
| 25 | #include "../../wusbcore/wusbhc.h" | 23 | #include "../../wusbcore/wusbhc.h" |
| 26 | 24 | ||
| 27 | #include "whcd.h" | 25 | #include "whcd.h" |
| 28 | 26 | ||
| 29 | #if D_LOCAL >= 4 | ||
| 30 | static void dump_pzl(struct whc *whc, const char *tag) | ||
| 31 | { | ||
| 32 | struct device *dev = &whc->umc->dev; | ||
| 33 | struct whc_qset *qset; | ||
| 34 | int period = 0; | ||
| 35 | |||
| 36 | d_printf(4, dev, "PZL %s\n", tag); | ||
| 37 | |||
| 38 | for (period = 0; period < 5; period++) { | ||
| 39 | d_printf(4, dev, "Period %d\n", period); | ||
| 40 | list_for_each_entry(qset, &whc->periodic_list[period], list_node) { | ||
| 41 | dump_qset(qset, dev); | ||
| 42 | } | ||
| 43 | } | ||
| 44 | } | ||
| 45 | #else | ||
| 46 | static inline void dump_pzl(struct whc *whc, const char *tag) | ||
| 47 | { | ||
| 48 | } | ||
| 49 | #endif | ||
| 50 | |||
| 51 | static void update_pzl_pointers(struct whc *whc, int period, u64 addr) | 27 | static void update_pzl_pointers(struct whc *whc, int period, u64 addr) |
| 52 | { | 28 | { |
| 53 | switch (period) { | 29 | switch (period) { |
| @@ -195,11 +171,26 @@ void pzl_stop(struct whc *whc) | |||
| 195 | 1000, "stop PZL"); | 171 | 1000, "stop PZL"); |
| 196 | } | 172 | } |
| 197 | 173 | ||
| 174 | /** | ||
| 175 | * pzl_update - request a PZL update and wait for the hardware to be synced | ||
| 176 | * @whc: the WHCI HC | ||
| 177 | * @wusbcmd: WUSBCMD value to start the update. | ||
| 178 | * | ||
| 179 | * If the WUSB HC is inactive (i.e., the PZL is stopped) then the | ||
| 180 | * update must be skipped as the hardware may not respond to update | ||
| 181 | * requests. | ||
| 182 | */ | ||
| 198 | void pzl_update(struct whc *whc, uint32_t wusbcmd) | 183 | void pzl_update(struct whc *whc, uint32_t wusbcmd) |
| 199 | { | 184 | { |
| 200 | whc_write_wusbcmd(whc, wusbcmd, wusbcmd); | 185 | struct wusbhc *wusbhc = &whc->wusbhc; |
| 201 | wait_event(whc->periodic_list_wq, | 186 | |
| 202 | (le_readl(whc->base + WUSBCMD) & WUSBCMD_PERIODIC_UPDATED) == 0); | 187 | mutex_lock(&wusbhc->mutex); |
| 188 | if (wusbhc->active) { | ||
| 189 | whc_write_wusbcmd(whc, wusbcmd, wusbcmd); | ||
| 190 | wait_event(whc->periodic_list_wq, | ||
| 191 | (le_readl(whc->base + WUSBCMD) & WUSBCMD_PERIODIC_UPDATED) == 0); | ||
| 192 | } | ||
| 193 | mutex_unlock(&wusbhc->mutex); | ||
| 203 | } | 194 | } |
| 204 | 195 | ||
| 205 | static void update_pzl_hw_view(struct whc *whc) | 196 | static void update_pzl_hw_view(struct whc *whc) |
| @@ -235,8 +226,6 @@ void scan_periodic_work(struct work_struct *work) | |||
| 235 | 226 | ||
| 236 | spin_lock_irq(&whc->lock); | 227 | spin_lock_irq(&whc->lock); |
| 237 | 228 | ||
| 238 | dump_pzl(whc, "before processing"); | ||
| 239 | |||
| 240 | for (period = 4; period >= 0; period--) { | 229 | for (period = 4; period >= 0; period--) { |
| 241 | list_for_each_entry_safe(qset, t, &whc->periodic_list[period], list_node) { | 230 | list_for_each_entry_safe(qset, t, &whc->periodic_list[period], list_node) { |
| 242 | if (!qset->in_hw_list) | 231 | if (!qset->in_hw_list) |
| @@ -248,8 +237,6 @@ void scan_periodic_work(struct work_struct *work) | |||
| 248 | if (update & (WHC_UPDATE_ADDED | WHC_UPDATE_REMOVED)) | 237 | if (update & (WHC_UPDATE_ADDED | WHC_UPDATE_REMOVED)) |
| 249 | update_pzl_hw_view(whc); | 238 | update_pzl_hw_view(whc); |
| 250 | 239 | ||
| 251 | dump_pzl(whc, "after processing"); | ||
| 252 | |||
| 253 | spin_unlock_irq(&whc->lock); | 240 | spin_unlock_irq(&whc->lock); |
| 254 | 241 | ||
| 255 | if (update) { | 242 | if (update) { |
diff --git a/drivers/usb/host/whci/qset.c b/drivers/usb/host/whci/qset.c index 0420037d2e1..7be74314ee1 100644 --- a/drivers/usb/host/whci/qset.c +++ b/drivers/usb/host/whci/qset.c | |||
| @@ -24,46 +24,6 @@ | |||
| 24 | 24 | ||
| 25 | #include "whcd.h" | 25 | #include "whcd.h" |
| 26 | 26 | ||
| 27 | void dump_qset(struct whc_qset *qset, struct device *dev) | ||
| 28 | { | ||
| 29 | struct whc_std *std; | ||
| 30 | struct urb *urb = NULL; | ||
| 31 | int i; | ||
| 32 | |||
| 33 | dev_dbg(dev, "qset %08x\n", (u32)qset->qset_dma); | ||
| 34 | dev_dbg(dev, " -> %08x\n", (u32)qset->qh.link); | ||
| 35 | dev_dbg(dev, " info: %08x %08x %08x\n", | ||
| 36 | qset->qh.info1, qset->qh.info2, qset->qh.info3); | ||
| 37 | dev_dbg(dev, " sts: %04x errs: %d\n", qset->qh.status, qset->qh.err_count); | ||
| 38 | dev_dbg(dev, " TD: sts: %08x opts: %08x\n", | ||
| 39 | qset->qh.overlay.qtd.status, qset->qh.overlay.qtd.options); | ||
| 40 | |||
| 41 | for (i = 0; i < WHCI_QSET_TD_MAX; i++) { | ||
| 42 | dev_dbg(dev, " %c%c TD[%d]: sts: %08x opts: %08x ptr: %08x\n", | ||
| 43 | i == qset->td_start ? 'S' : ' ', | ||
| 44 | i == qset->td_end ? 'E' : ' ', | ||
| 45 | i, qset->qtd[i].status, qset->qtd[i].options, | ||
| 46 | (u32)qset->qtd[i].page_list_ptr); | ||
| 47 | } | ||
| 48 | dev_dbg(dev, " ntds: %d\n", qset->ntds); | ||
| 49 | list_for_each_entry(std, &qset->stds, list_node) { | ||
| 50 | if (urb != std->urb) { | ||
| 51 | urb = std->urb; | ||
| 52 | dev_dbg(dev, " urb %p transferred: %d bytes\n", urb, | ||
| 53 | urb->actual_length); | ||
| 54 | } | ||
| 55 | if (std->qtd) | ||
| 56 | dev_dbg(dev, " sTD[%td]: %zu bytes @ %08x\n", | ||
| 57 | std->qtd - &qset->qtd[0], | ||
| 58 | std->len, std->num_pointers ? | ||
| 59 | (u32)(std->pl_virt[0].buf_ptr) : (u32)std->dma_addr); | ||
| 60 | else | ||
| 61 | dev_dbg(dev, " sTD[-]: %zd bytes @ %08x\n", | ||
| 62 | std->len, std->num_pointers ? | ||
| 63 | (u32)(std->pl_virt[0].buf_ptr) : (u32)std->dma_addr); | ||
| 64 | } | ||
| 65 | } | ||
| 66 | |||
| 67 | struct whc_qset *qset_alloc(struct whc *whc, gfp_t mem_flags) | 27 | struct whc_qset *qset_alloc(struct whc *whc, gfp_t mem_flags) |
| 68 | { | 28 | { |
| 69 | struct whc_qset *qset; | 29 | struct whc_qset *qset; |
diff --git a/drivers/usb/host/whci/whcd.h b/drivers/usb/host/whci/whcd.h index 1d2a53bd39f..0f3540f04f5 100644 --- a/drivers/usb/host/whci/whcd.h +++ b/drivers/usb/host/whci/whcd.h | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #define __WHCD_H | 21 | #define __WHCD_H |
| 22 | 22 | ||
| 23 | #include <linux/uwb/whci.h> | 23 | #include <linux/uwb/whci.h> |
| 24 | #include <linux/uwb/umc.h> | ||
| 24 | #include <linux/workqueue.h> | 25 | #include <linux/workqueue.h> |
| 25 | 26 | ||
| 26 | #include "whci-hc.h" | 27 | #include "whci-hc.h" |
| @@ -28,6 +29,7 @@ | |||
| 28 | /* Generic command timeout. */ | 29 | /* Generic command timeout. */ |
| 29 | #define WHC_GENCMD_TIMEOUT_MS 100 | 30 | #define WHC_GENCMD_TIMEOUT_MS 100 |
| 30 | 31 | ||
| 32 | struct whc_dbg; | ||
| 31 | 33 | ||
| 32 | struct whc { | 34 | struct whc { |
| 33 | struct wusbhc wusbhc; | 35 | struct wusbhc wusbhc; |
| @@ -69,6 +71,8 @@ struct whc { | |||
| 69 | struct list_head periodic_removed_list; | 71 | struct list_head periodic_removed_list; |
| 70 | wait_queue_head_t periodic_list_wq; | 72 | wait_queue_head_t periodic_list_wq; |
| 71 | struct work_struct periodic_work; | 73 | struct work_struct periodic_work; |
| 74 | |||
| 75 | struct whc_dbg *dbg; | ||
| 72 | }; | 76 | }; |
| 73 | 77 | ||
| 74 | #define wusbhc_to_whc(w) (container_of((w), struct whc, wusbhc)) | 78 | #define wusbhc_to_whc(w) (container_of((w), struct whc, wusbhc)) |
| @@ -136,7 +140,7 @@ int whc_do_gencmd(struct whc *whc, u32 cmd, u32 params, void *addr, size_t len); | |||
| 136 | 140 | ||
| 137 | /* wusb.c */ | 141 | /* wusb.c */ |
| 138 | int whc_wusbhc_start(struct wusbhc *wusbhc); | 142 | int whc_wusbhc_start(struct wusbhc *wusbhc); |
| 139 | void whc_wusbhc_stop(struct wusbhc *wusbhc); | 143 | void whc_wusbhc_stop(struct wusbhc *wusbhc, int delay); |
| 140 | int whc_mmcie_add(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt, | 144 | int whc_mmcie_add(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt, |
| 141 | u8 handle, struct wuie_hdr *wuie); | 145 | u8 handle, struct wuie_hdr *wuie); |
| 142 | int whc_mmcie_rm(struct wusbhc *wusbhc, u8 handle); | 146 | int whc_mmcie_rm(struct wusbhc *wusbhc, u8 handle); |
| @@ -190,8 +194,11 @@ void process_inactive_qtd(struct whc *whc, struct whc_qset *qset, | |||
| 190 | struct whc_qtd *qtd); | 194 | struct whc_qtd *qtd); |
| 191 | enum whc_update qset_add_qtds(struct whc *whc, struct whc_qset *qset); | 195 | enum whc_update qset_add_qtds(struct whc *whc, struct whc_qset *qset); |
| 192 | void qset_remove_complete(struct whc *whc, struct whc_qset *qset); | 196 | void qset_remove_complete(struct whc *whc, struct whc_qset *qset); |
| 193 | void dump_qset(struct whc_qset *qset, struct device *dev); | ||
| 194 | void pzl_update(struct whc *whc, uint32_t wusbcmd); | 197 | void pzl_update(struct whc *whc, uint32_t wusbcmd); |
| 195 | void asl_update(struct whc *whc, uint32_t wusbcmd); | 198 | void asl_update(struct whc *whc, uint32_t wusbcmd); |
| 196 | 199 | ||
| 200 | /* debug.c */ | ||
| 201 | void whc_dbg_init(struct whc *whc); | ||
| 202 | void whc_dbg_clean_up(struct whc *whc); | ||
| 203 | |||
| 197 | #endif /* #ifndef __WHCD_H */ | 204 | #endif /* #ifndef __WHCD_H */ |
diff --git a/drivers/usb/host/whci/whci-hc.h b/drivers/usb/host/whci/whci-hc.h index bff1eb7a35c..51df7e313b3 100644 --- a/drivers/usb/host/whci/whci-hc.h +++ b/drivers/usb/host/whci/whci-hc.h | |||
| @@ -410,6 +410,8 @@ struct dn_buf_entry { | |||
| 410 | # define WUSBDNTSCTRL_SLOTS(s) ((s) << 0) | 410 | # define WUSBDNTSCTRL_SLOTS(s) ((s) << 0) |
| 411 | 411 | ||
| 412 | #define WUSBTIME 0x68 | 412 | #define WUSBTIME 0x68 |
| 413 | # define WUSBTIME_CHANNEL_TIME_MASK 0x00ffffff | ||
| 414 | |||
| 413 | #define WUSBBPST 0x6c | 415 | #define WUSBBPST 0x6c |
| 414 | #define WUSBDIBUPDATED 0x70 | 416 | #define WUSBDIBUPDATED 0x70 |
| 415 | 417 | ||
diff --git a/drivers/usb/host/whci/wusb.c b/drivers/usb/host/whci/wusb.c index 66e4ddcd961..f24efdebad1 100644 --- a/drivers/usb/host/whci/wusb.c +++ b/drivers/usb/host/whci/wusb.c | |||
| @@ -15,47 +15,19 @@ | |||
| 15 | * You should have received a copy of the GNU General Public License | 15 | * You should have received a copy of the GNU General Public License |
| 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 17 | */ | 17 | */ |
| 18 | #include <linux/version.h> | ||
| 19 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
| 20 | #include <linux/init.h> | 19 | #include <linux/init.h> |
| 21 | #include <linux/uwb/umc.h> | 20 | #include <linux/uwb/umc.h> |
| 22 | #define D_LOCAL 1 | ||
| 23 | #include <linux/uwb/debug.h> | ||
| 24 | 21 | ||
| 25 | #include "../../wusbcore/wusbhc.h" | 22 | #include "../../wusbcore/wusbhc.h" |
| 26 | 23 | ||
| 27 | #include "whcd.h" | 24 | #include "whcd.h" |
| 28 | 25 | ||
| 29 | #if D_LOCAL >= 1 | ||
| 30 | static void dump_di(struct whc *whc, int idx) | ||
| 31 | { | ||
| 32 | struct di_buf_entry *di = &whc->di_buf[idx]; | ||
| 33 | struct device *dev = &whc->umc->dev; | ||
| 34 | char buf[128]; | ||
| 35 | |||
| 36 | bitmap_scnprintf(buf, sizeof(buf), (unsigned long *)di->availability_info, UWB_NUM_MAS); | ||
| 37 | |||
| 38 | d_printf(1, dev, "DI[%d]\n", idx); | ||
| 39 | d_printf(1, dev, " availability: %s\n", buf); | ||
| 40 | d_printf(1, dev, " %c%c key idx: %d dev addr: %d\n", | ||
| 41 | (di->addr_sec_info & WHC_DI_SECURE) ? 'S' : ' ', | ||
| 42 | (di->addr_sec_info & WHC_DI_DISABLE) ? 'D' : ' ', | ||
| 43 | (di->addr_sec_info & WHC_DI_KEY_IDX_MASK) >> 8, | ||
| 44 | (di->addr_sec_info & WHC_DI_DEV_ADDR_MASK)); | ||
| 45 | } | ||
| 46 | #else | ||
| 47 | static inline void dump_di(struct whc *whc, int idx) | ||
| 48 | { | ||
| 49 | } | ||
| 50 | #endif | ||
| 51 | |||
| 52 | static int whc_update_di(struct whc *whc, int idx) | 26 | static int whc_update_di(struct whc *whc, int idx) |
| 53 | { | 27 | { |
| 54 | int offset = idx / 32; | 28 | int offset = idx / 32; |
| 55 | u32 bit = 1 << (idx % 32); | 29 | u32 bit = 1 << (idx % 32); |
| 56 | 30 | ||
| 57 | dump_di(whc, idx); | ||
| 58 | |||
| 59 | le_writel(bit, whc->base + WUSBDIBUPDATED + offset); | 31 | le_writel(bit, whc->base + WUSBDIBUPDATED + offset); |
| 60 | 32 | ||
| 61 | return whci_wait_for(&whc->umc->dev, | 33 | return whci_wait_for(&whc->umc->dev, |
| @@ -64,8 +36,9 @@ static int whc_update_di(struct whc *whc, int idx) | |||
| 64 | } | 36 | } |
| 65 | 37 | ||
| 66 | /* | 38 | /* |
| 67 | * WHCI starts and stops MMCs based on there being a valid GTK so | 39 | * WHCI starts MMCs based on there being a valid GTK so these need |
| 68 | * these need only start/stop the asynchronous and periodic schedules. | 40 | * only start/stop the asynchronous and periodic schedules and send a |
| 41 | * channel stop command. | ||
| 69 | */ | 42 | */ |
| 70 | 43 | ||
| 71 | int whc_wusbhc_start(struct wusbhc *wusbhc) | 44 | int whc_wusbhc_start(struct wusbhc *wusbhc) |
| @@ -78,12 +51,20 @@ int whc_wusbhc_start(struct wusbhc *wusbhc) | |||
| 78 | return 0; | 51 | return 0; |
| 79 | } | 52 | } |
| 80 | 53 | ||
| 81 | void whc_wusbhc_stop(struct wusbhc *wusbhc) | 54 | void whc_wusbhc_stop(struct wusbhc *wusbhc, int delay) |
| 82 | { | 55 | { |
| 83 | struct whc *whc = wusbhc_to_whc(wusbhc); | 56 | struct whc *whc = wusbhc_to_whc(wusbhc); |
| 57 | u32 stop_time, now_time; | ||
| 58 | int ret; | ||
| 84 | 59 | ||
| 85 | pzl_stop(whc); | 60 | pzl_stop(whc); |
| 86 | asl_stop(whc); | 61 | asl_stop(whc); |
| 62 | |||
| 63 | now_time = le_readl(whc->base + WUSBTIME) & WUSBTIME_CHANNEL_TIME_MASK; | ||
| 64 | stop_time = (now_time + ((delay * 8) << 7)) & 0x00ffffff; | ||
| 65 | ret = whc_do_gencmd(whc, WUSBGENCMDSTS_CHAN_STOP, stop_time, NULL, 0); | ||
| 66 | if (ret == 0) | ||
| 67 | msleep(delay); | ||
| 87 | } | 68 | } |
| 88 | 69 | ||
| 89 | int whc_mmcie_add(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt, | 70 | int whc_mmcie_add(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt, |
diff --git a/drivers/usb/wusbcore/cbaf.c b/drivers/usb/wusbcore/cbaf.c index ab4788d1785..1335cbe1191 100644 --- a/drivers/usb/wusbcore/cbaf.c +++ b/drivers/usb/wusbcore/cbaf.c | |||
| @@ -88,7 +88,6 @@ | |||
| 88 | */ | 88 | */ |
| 89 | #include <linux/module.h> | 89 | #include <linux/module.h> |
| 90 | #include <linux/ctype.h> | 90 | #include <linux/ctype.h> |
| 91 | #include <linux/version.h> | ||
| 92 | #include <linux/usb.h> | 91 | #include <linux/usb.h> |
| 93 | #include <linux/interrupt.h> | 92 | #include <linux/interrupt.h> |
| 94 | #include <linux/delay.h> | 93 | #include <linux/delay.h> |
diff --git a/drivers/usb/wusbcore/crypto.c b/drivers/usb/wusbcore/crypto.c index c36c4389baa..9ec7fd5da48 100644 --- a/drivers/usb/wusbcore/crypto.c +++ b/drivers/usb/wusbcore/crypto.c | |||
| @@ -51,9 +51,17 @@ | |||
| 51 | #include <linux/uwb.h> | 51 | #include <linux/uwb.h> |
| 52 | #include <linux/usb/wusb.h> | 52 | #include <linux/usb/wusb.h> |
| 53 | #include <linux/scatterlist.h> | 53 | #include <linux/scatterlist.h> |
| 54 | #define D_LOCAL 0 | ||
| 55 | #include <linux/uwb/debug.h> | ||
| 56 | 54 | ||
| 55 | static int debug_crypto_verify = 0; | ||
| 56 | |||
| 57 | module_param(debug_crypto_verify, int, 0); | ||
| 58 | MODULE_PARM_DESC(debug_crypto_verify, "verify the key generation algorithms"); | ||
| 59 | |||
| 60 | static void wusb_key_dump(const void *buf, size_t len) | ||
| 61 | { | ||
| 62 | print_hex_dump(KERN_ERR, " ", DUMP_PREFIX_OFFSET, 16, 1, | ||
| 63 | buf, len, 0); | ||
| 64 | } | ||
| 57 | 65 | ||
| 58 | /* | 66 | /* |
| 59 | * Block of data, as understood by AES-CCM | 67 | * Block of data, as understood by AES-CCM |
| @@ -203,9 +211,6 @@ static int wusb_ccm_mac(struct crypto_blkcipher *tfm_cbc, | |||
| 203 | const u8 bzero[16] = { 0 }; | 211 | const u8 bzero[16] = { 0 }; |
| 204 | size_t zero_padding; | 212 | size_t zero_padding; |
| 205 | 213 | ||
| 206 | d_fnstart(3, NULL, "(tfm_cbc %p, tfm_aes %p, mic %p, " | ||
| 207 | "n %p, a %p, b %p, blen %zu)\n", | ||
| 208 | tfm_cbc, tfm_aes, mic, n, a, b, blen); | ||
| 209 | /* | 214 | /* |
| 210 | * These checks should be compile time optimized out | 215 | * These checks should be compile time optimized out |
| 211 | * ensure @a fills b1's mac_header and following fields | 216 | * ensure @a fills b1's mac_header and following fields |
| @@ -247,16 +252,6 @@ static int wusb_ccm_mac(struct crypto_blkcipher *tfm_cbc, | |||
| 247 | b1.la = cpu_to_be16(blen + 14); | 252 | b1.la = cpu_to_be16(blen + 14); |
| 248 | memcpy(&b1.mac_header, a, sizeof(*a)); | 253 | memcpy(&b1.mac_header, a, sizeof(*a)); |
| 249 | 254 | ||
| 250 | d_printf(4, NULL, "I: B0 (%zu bytes)\n", sizeof(b0)); | ||
| 251 | d_dump(4, NULL, &b0, sizeof(b0)); | ||
| 252 | d_printf(4, NULL, "I: B1 (%zu bytes)\n", sizeof(b1)); | ||
| 253 | d_dump(4, NULL, &b1, sizeof(b1)); | ||
| 254 | d_printf(4, NULL, "I: B (%zu bytes)\n", blen); | ||
| 255 | d_dump(4, NULL, b, blen); | ||
| 256 | d_printf(4, NULL, "I: B 0-padding (%zu bytes)\n", zero_padding); | ||
| 257 | d_printf(4, NULL, "D: IV before crypto (%zu)\n", ivsize); | ||
| 258 | d_dump(4, NULL, iv, ivsize); | ||
| 259 | |||
| 260 | sg_init_table(sg, ARRAY_SIZE(sg)); | 255 | sg_init_table(sg, ARRAY_SIZE(sg)); |
| 261 | sg_set_buf(&sg[0], &b0, sizeof(b0)); | 256 | sg_set_buf(&sg[0], &b0, sizeof(b0)); |
| 262 | sg_set_buf(&sg[1], &b1, sizeof(b1)); | 257 | sg_set_buf(&sg[1], &b1, sizeof(b1)); |
| @@ -273,8 +268,6 @@ static int wusb_ccm_mac(struct crypto_blkcipher *tfm_cbc, | |||
| 273 | result); | 268 | result); |
| 274 | goto error_cbc_crypt; | 269 | goto error_cbc_crypt; |
| 275 | } | 270 | } |
| 276 | d_printf(4, NULL, "D: MIC tag\n"); | ||
| 277 | d_dump(4, NULL, iv, ivsize); | ||
| 278 | 271 | ||
| 279 | /* Now we crypt the MIC Tag (*iv) with Ax -- values per WUSB1.0[6.5] | 272 | /* Now we crypt the MIC Tag (*iv) with Ax -- values per WUSB1.0[6.5] |
| 280 | * The procedure is to AES crypt the A0 block and XOR the MIC | 273 | * The procedure is to AES crypt the A0 block and XOR the MIC |
| @@ -289,17 +282,10 @@ static int wusb_ccm_mac(struct crypto_blkcipher *tfm_cbc, | |||
| 289 | ax.counter = 0; | 282 | ax.counter = 0; |
| 290 | crypto_cipher_encrypt_one(tfm_aes, (void *)&ax, (void *)&ax); | 283 | crypto_cipher_encrypt_one(tfm_aes, (void *)&ax, (void *)&ax); |
| 291 | bytewise_xor(mic, &ax, iv, 8); | 284 | bytewise_xor(mic, &ax, iv, 8); |
| 292 | d_printf(4, NULL, "D: CTR[MIC]\n"); | ||
| 293 | d_dump(4, NULL, &ax, 8); | ||
| 294 | d_printf(4, NULL, "D: CCM-MIC tag\n"); | ||
| 295 | d_dump(4, NULL, mic, 8); | ||
| 296 | result = 8; | 285 | result = 8; |
| 297 | error_cbc_crypt: | 286 | error_cbc_crypt: |
| 298 | kfree(dst_buf); | 287 | kfree(dst_buf); |
| 299 | error_dst_buf: | 288 | error_dst_buf: |
| 300 | d_fnend(3, NULL, "(tfm_cbc %p, tfm_aes %p, mic %p, " | ||
| 301 | "n %p, a %p, b %p, blen %zu)\n", | ||
| 302 | tfm_cbc, tfm_aes, mic, n, a, b, blen); | ||
| 303 | return result; | 289 | return result; |
| 304 | } | 290 | } |
| 305 | 291 | ||
| @@ -321,10 +307,6 @@ ssize_t wusb_prf(void *out, size_t out_size, | |||
| 321 | u64 sfn = 0; | 307 | u64 sfn = 0; |
| 322 | __le64 sfn_le; | 308 | __le64 sfn_le; |
| 323 | 309 | ||
| 324 | d_fnstart(3, NULL, "(out %p, out_size %zu, key %p, _n %p, " | ||
| 325 | "a %p, b %p, blen %zu, len %zu)\n", out, out_size, | ||
| 326 | key, _n, a, b, blen, len); | ||
| 327 | |||
| 328 | tfm_cbc = crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC); | 310 | tfm_cbc = crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC); |
| 329 | if (IS_ERR(tfm_cbc)) { | 311 | if (IS_ERR(tfm_cbc)) { |
| 330 | result = PTR_ERR(tfm_cbc); | 312 | result = PTR_ERR(tfm_cbc); |
| @@ -366,9 +348,6 @@ error_alloc_aes: | |||
| 366 | error_setkey_cbc: | 348 | error_setkey_cbc: |
| 367 | crypto_free_blkcipher(tfm_cbc); | 349 | crypto_free_blkcipher(tfm_cbc); |
| 368 | error_alloc_cbc: | 350 | error_alloc_cbc: |
| 369 | d_fnend(3, NULL, "(out %p, out_size %zu, key %p, _n %p, " | ||
| 370 | "a %p, b %p, blen %zu, len %zu) = %d\n", out, out_size, | ||
| 371 | key, _n, a, b, blen, len, (int)bytes); | ||
| 372 | return result; | 351 | return result; |
| 373 | } | 352 | } |
| 374 | 353 | ||
| @@ -422,14 +401,14 @@ static int wusb_oob_mic_verify(void) | |||
| 422 | "mismatch between MIC result and WUSB1.0[A2]\n"); | 401 | "mismatch between MIC result and WUSB1.0[A2]\n"); |
| 423 | hs_size = sizeof(stv_hsmic_hs) - sizeof(stv_hsmic_hs.MIC); | 402 | hs_size = sizeof(stv_hsmic_hs) - sizeof(stv_hsmic_hs.MIC); |
| 424 | printk(KERN_ERR "E: Handshake2 in: (%zu bytes)\n", hs_size); | 403 | printk(KERN_ERR "E: Handshake2 in: (%zu bytes)\n", hs_size); |
| 425 | dump_bytes(NULL, &stv_hsmic_hs, hs_size); | 404 | wusb_key_dump(&stv_hsmic_hs, hs_size); |
| 426 | printk(KERN_ERR "E: CCM Nonce in: (%zu bytes)\n", | 405 | printk(KERN_ERR "E: CCM Nonce in: (%zu bytes)\n", |
| 427 | sizeof(stv_hsmic_n)); | 406 | sizeof(stv_hsmic_n)); |
| 428 | dump_bytes(NULL, &stv_hsmic_n, sizeof(stv_hsmic_n)); | 407 | wusb_key_dump(&stv_hsmic_n, sizeof(stv_hsmic_n)); |
| 429 | printk(KERN_ERR "E: MIC out:\n"); | 408 | printk(KERN_ERR "E: MIC out:\n"); |
| 430 | dump_bytes(NULL, mic, sizeof(mic)); | 409 | wusb_key_dump(mic, sizeof(mic)); |
| 431 | printk(KERN_ERR "E: MIC out (from WUSB1.0[A.2]):\n"); | 410 | printk(KERN_ERR "E: MIC out (from WUSB1.0[A.2]):\n"); |
| 432 | dump_bytes(NULL, stv_hsmic_hs.MIC, sizeof(stv_hsmic_hs.MIC)); | 411 | wusb_key_dump(stv_hsmic_hs.MIC, sizeof(stv_hsmic_hs.MIC)); |
| 433 | result = -EINVAL; | 412 | result = -EINVAL; |
| 434 | } else | 413 | } else |
| 435 | result = 0; | 414 | result = 0; |
| @@ -497,19 +476,16 @@ static int wusb_key_derive_verify(void) | |||
| 497 | printk(KERN_ERR "E: WUSB key derivation test: " | 476 | printk(KERN_ERR "E: WUSB key derivation test: " |
| 498 | "mismatch between key derivation result " | 477 | "mismatch between key derivation result " |
| 499 | "and WUSB1.0[A1] Errata 2006/12\n"); | 478 | "and WUSB1.0[A1] Errata 2006/12\n"); |
| 500 | printk(KERN_ERR "E: keydvt in: key (%zu bytes)\n", | 479 | printk(KERN_ERR "E: keydvt in: key\n"); |
| 501 | sizeof(stv_key_a1)); | 480 | wusb_key_dump(stv_key_a1, sizeof(stv_key_a1)); |
| 502 | dump_bytes(NULL, stv_key_a1, sizeof(stv_key_a1)); | 481 | printk(KERN_ERR "E: keydvt in: nonce\n"); |
| 503 | printk(KERN_ERR "E: keydvt in: nonce (%zu bytes)\n", | 482 | wusb_key_dump( &stv_keydvt_n_a1, sizeof(stv_keydvt_n_a1)); |
| 504 | sizeof(stv_keydvt_n_a1)); | 483 | printk(KERN_ERR "E: keydvt in: hnonce & dnonce\n"); |
| 505 | dump_bytes(NULL, &stv_keydvt_n_a1, sizeof(stv_keydvt_n_a1)); | 484 | wusb_key_dump(&stv_keydvt_in_a1, sizeof(stv_keydvt_in_a1)); |
| 506 | printk(KERN_ERR "E: keydvt in: hnonce & dnonce (%zu bytes)\n", | ||
| 507 | sizeof(stv_keydvt_in_a1)); | ||
| 508 | dump_bytes(NULL, &stv_keydvt_in_a1, sizeof(stv_keydvt_in_a1)); | ||
| 509 | printk(KERN_ERR "E: keydvt out: KCK\n"); | 485 | printk(KERN_ERR "E: keydvt out: KCK\n"); |
| 510 | dump_bytes(NULL, &keydvt_out.kck, sizeof(keydvt_out.kck)); | 486 | wusb_key_dump(&keydvt_out.kck, sizeof(keydvt_out.kck)); |
| 511 | printk(KERN_ERR "E: keydvt out: PTK\n"); | 487 | printk(KERN_ERR "E: keydvt out: PTK\n"); |
| 512 | dump_bytes(NULL, &keydvt_out.ptk, sizeof(keydvt_out.ptk)); | 488 | wusb_key_dump(&keydvt_out.ptk, sizeof(keydvt_out.ptk)); |
| 513 | result = -EINVAL; | 489 | result = -EINVAL; |
| 514 | } else | 490 | } else |
| 515 | result = 0; | 491 | result = 0; |
| @@ -526,10 +502,13 @@ int wusb_crypto_init(void) | |||
| 526 | { | 502 | { |
| 527 | int result; | 503 | int result; |
| 528 | 504 | ||
| 529 | result = wusb_key_derive_verify(); | 505 | if (debug_crypto_verify) { |
| 530 | if (result < 0) | 506 | result = wusb_key_derive_verify(); |
| 531 | return result; | 507 | if (result < 0) |
| 532 | return wusb_oob_mic_verify(); | 508 | return result; |
| 509 | return wusb_oob_mic_verify(); | ||
| 510 | } | ||
| 511 | return 0; | ||
| 533 | } | 512 | } |
| 534 | 513 | ||
| 535 | void wusb_crypto_exit(void) | 514 | void wusb_crypto_exit(void) |
diff --git a/drivers/usb/wusbcore/dev-sysfs.c b/drivers/usb/wusbcore/dev-sysfs.c index 7897a19652e..10183457623 100644 --- a/drivers/usb/wusbcore/dev-sysfs.c +++ b/drivers/usb/wusbcore/dev-sysfs.c | |||
| @@ -28,10 +28,6 @@ | |||
| 28 | #include <linux/workqueue.h> | 28 | #include <linux/workqueue.h> |
| 29 | #include "wusbhc.h" | 29 | #include "wusbhc.h" |
| 30 | 30 | ||
| 31 | #undef D_LOCAL | ||
| 32 | #define D_LOCAL 4 | ||
| 33 | #include <linux/uwb/debug.h> | ||
| 34 | |||
| 35 | static ssize_t wusb_disconnect_store(struct device *dev, | 31 | static ssize_t wusb_disconnect_store(struct device *dev, |
| 36 | struct device_attribute *attr, | 32 | struct device_attribute *attr, |
| 37 | const char *buf, size_t size) | 33 | const char *buf, size_t size) |
diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c index f45d777bef3..e2e7e4bc846 100644 --- a/drivers/usb/wusbcore/devconnect.c +++ b/drivers/usb/wusbcore/devconnect.c | |||
| @@ -57,9 +57,6 @@ | |||
| 57 | * Called by notif.c:wusb_handle_dn_connect() | 57 | * Called by notif.c:wusb_handle_dn_connect() |
| 58 | * when a DN_Connect is received. | 58 | * when a DN_Connect is received. |
| 59 | * | 59 | * |
| 60 | * wusbhc_devconnect_auth() Called by rh.c:wusbhc_rh_port_reset() when | ||
| 61 | * doing the device connect sequence. | ||
| 62 | * | ||
| 63 | * wusb_devconnect_acked() Ack done, release resources. | 60 | * wusb_devconnect_acked() Ack done, release resources. |
| 64 | * | 61 | * |
| 65 | * wusb_handle_dn_alive() Called by notif.c:wusb_handle_dn() | 62 | * wusb_handle_dn_alive() Called by notif.c:wusb_handle_dn() |
| @@ -69,9 +66,6 @@ | |||
| 69 | * process a disconenct request from a | 66 | * process a disconenct request from a |
| 70 | * device. | 67 | * device. |
| 71 | * | 68 | * |
| 72 | * wusb_dev_reset() Called by rh.c:wusbhc_rh_port_reset() when | ||
| 73 | * resetting a device. | ||
| 74 | * | ||
| 75 | * __wusb_dev_disable() Called by rh.c:wusbhc_rh_clear_port_feat() when | 69 | * __wusb_dev_disable() Called by rh.c:wusbhc_rh_clear_port_feat() when |
| 76 | * disabling a port. | 70 | * disabling a port. |
| 77 | * | 71 | * |
| @@ -97,10 +91,6 @@ | |||
| 97 | #include <linux/workqueue.h> | 91 | #include <linux/workqueue.h> |
| 98 | #include "wusbhc.h" | 92 | #include "wusbhc.h" |
| 99 | 93 | ||
| 100 | #undef D_LOCAL | ||
| 101 | #define D_LOCAL 1 | ||
| 102 | #include <linux/uwb/debug.h> | ||
| 103 | |||
| 104 | static void wusbhc_devconnect_acked_work(struct work_struct *work); | 94 | static void wusbhc_devconnect_acked_work(struct work_struct *work); |
| 105 | 95 | ||
| 106 | static void wusb_dev_free(struct wusb_dev *wusb_dev) | 96 | static void wusb_dev_free(struct wusb_dev *wusb_dev) |
| @@ -240,6 +230,7 @@ static struct wusb_dev *wusbhc_cack_add(struct wusbhc *wusbhc, | |||
| 240 | list_add_tail(&wusb_dev->cack_node, &wusbhc->cack_list); | 230 | list_add_tail(&wusb_dev->cack_node, &wusbhc->cack_list); |
| 241 | wusbhc->cack_count++; | 231 | wusbhc->cack_count++; |
| 242 | wusbhc_fill_cack_ie(wusbhc); | 232 | wusbhc_fill_cack_ie(wusbhc); |
| 233 | |||
| 243 | return wusb_dev; | 234 | return wusb_dev; |
| 244 | } | 235 | } |
| 245 | 236 | ||
| @@ -250,12 +241,9 @@ static struct wusb_dev *wusbhc_cack_add(struct wusbhc *wusbhc, | |||
| 250 | */ | 241 | */ |
| 251 | static void wusbhc_cack_rm(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev) | 242 | static void wusbhc_cack_rm(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev) |
| 252 | { | 243 | { |
| 253 | struct device *dev = wusbhc->dev; | ||
| 254 | d_fnstart(3, dev, "(wusbhc %p wusb_dev %p)\n", wusbhc, wusb_dev); | ||
| 255 | list_del_init(&wusb_dev->cack_node); | 244 | list_del_init(&wusb_dev->cack_node); |
| 256 | wusbhc->cack_count--; | 245 | wusbhc->cack_count--; |
| 257 | wusbhc_fill_cack_ie(wusbhc); | 246 | wusbhc_fill_cack_ie(wusbhc); |
| 258 | d_fnend(3, dev, "(wusbhc %p wusb_dev %p) = void\n", wusbhc, wusb_dev); | ||
| 259 | } | 247 | } |
| 260 | 248 | ||
| 261 | /* | 249 | /* |
| @@ -263,14 +251,11 @@ static void wusbhc_cack_rm(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev) | |||
| 263 | static | 251 | static |
| 264 | void wusbhc_devconnect_acked(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev) | 252 | void wusbhc_devconnect_acked(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev) |
| 265 | { | 253 | { |
| 266 | struct device *dev = wusbhc->dev; | ||
| 267 | d_fnstart(3, dev, "(wusbhc %p wusb_dev %p)\n", wusbhc, wusb_dev); | ||
| 268 | wusbhc_cack_rm(wusbhc, wusb_dev); | 254 | wusbhc_cack_rm(wusbhc, wusb_dev); |
| 269 | if (wusbhc->cack_count) | 255 | if (wusbhc->cack_count) |
| 270 | wusbhc_mmcie_set(wusbhc, 0, 0, &wusbhc->cack_ie.hdr); | 256 | wusbhc_mmcie_set(wusbhc, 0, 0, &wusbhc->cack_ie.hdr); |
| 271 | else | 257 | else |
| 272 | wusbhc_mmcie_rm(wusbhc, &wusbhc->cack_ie.hdr); | 258 | wusbhc_mmcie_rm(wusbhc, &wusbhc->cack_ie.hdr); |
| 273 | d_fnend(3, dev, "(wusbhc %p wusb_dev %p) = void\n", wusbhc, wusb_dev); | ||
| 274 | } | 259 | } |
| 275 | 260 | ||
| 276 | static void wusbhc_devconnect_acked_work(struct work_struct *work) | 261 | static void wusbhc_devconnect_acked_work(struct work_struct *work) |
| @@ -320,7 +305,6 @@ void wusbhc_devconnect_ack(struct wusbhc *wusbhc, struct wusb_dn_connect *dnc, | |||
| 320 | struct wusb_port *port; | 305 | struct wusb_port *port; |
| 321 | unsigned idx, devnum; | 306 | unsigned idx, devnum; |
| 322 | 307 | ||
| 323 | d_fnstart(3, dev, "(%p, %p, %s)\n", wusbhc, dnc, pr_cdid); | ||
| 324 | mutex_lock(&wusbhc->mutex); | 308 | mutex_lock(&wusbhc->mutex); |
| 325 | 309 | ||
| 326 | /* Check we are not handling it already */ | 310 | /* Check we are not handling it already */ |
| @@ -366,16 +350,13 @@ void wusbhc_devconnect_ack(struct wusbhc *wusbhc, struct wusb_dn_connect *dnc, | |||
| 366 | port->wusb_dev = wusb_dev; | 350 | port->wusb_dev = wusb_dev; |
| 367 | port->status |= USB_PORT_STAT_CONNECTION; | 351 | port->status |= USB_PORT_STAT_CONNECTION; |
| 368 | port->change |= USB_PORT_STAT_C_CONNECTION; | 352 | port->change |= USB_PORT_STAT_C_CONNECTION; |
| 369 | port->reset_count = 0; | ||
| 370 | /* Now the port status changed to connected; khubd will | 353 | /* Now the port status changed to connected; khubd will |
| 371 | * pick the change up and try to reset the port to bring it to | 354 | * pick the change up and try to reset the port to bring it to |
| 372 | * the enabled state--so this process returns up to the stack | 355 | * the enabled state--so this process returns up to the stack |
| 373 | * and it calls back into wusbhc_rh_port_reset() who will call | 356 | * and it calls back into wusbhc_rh_port_reset(). |
| 374 | * devconnect_auth(). | ||
| 375 | */ | 357 | */ |
| 376 | error_unlock: | 358 | error_unlock: |
| 377 | mutex_unlock(&wusbhc->mutex); | 359 | mutex_unlock(&wusbhc->mutex); |
| 378 | d_fnend(3, dev, "(%p, %p, %s) = void\n", wusbhc, dnc, pr_cdid); | ||
| 379 | return; | 360 | return; |
| 380 | 361 | ||
| 381 | } | 362 | } |
| @@ -398,10 +379,8 @@ error_unlock: | |||
| 398 | static void __wusbhc_dev_disconnect(struct wusbhc *wusbhc, | 379 | static void __wusbhc_dev_disconnect(struct wusbhc *wusbhc, |
| 399 | struct wusb_port *port) | 380 | struct wusb_port *port) |
| 400 | { | 381 | { |
| 401 | struct device *dev = wusbhc->dev; | ||
| 402 | struct wusb_dev *wusb_dev = port->wusb_dev; | 382 | struct wusb_dev *wusb_dev = port->wusb_dev; |
| 403 | 383 | ||
| 404 | d_fnstart(3, dev, "(wusbhc %p, port %p)\n", wusbhc, port); | ||
| 405 | port->status &= ~(USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE | 384 | port->status &= ~(USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE |
| 406 | | USB_PORT_STAT_SUSPEND | USB_PORT_STAT_RESET | 385 | | USB_PORT_STAT_SUSPEND | USB_PORT_STAT_RESET |
| 407 | | USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED); | 386 | | USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED); |
| @@ -413,15 +392,11 @@ static void __wusbhc_dev_disconnect(struct wusbhc *wusbhc, | |||
| 413 | wusb_dev_put(wusb_dev); | 392 | wusb_dev_put(wusb_dev); |
| 414 | } | 393 | } |
| 415 | port->wusb_dev = NULL; | 394 | port->wusb_dev = NULL; |
| 416 | /* don't reset the reset_count to zero or wusbhc_rh_port_reset will get | ||
| 417 | * confused! We only reset to zero when we connect a new device. | ||
| 418 | */ | ||
| 419 | 395 | ||
| 420 | /* After a device disconnects, change the GTK (see [WUSB] | 396 | /* After a device disconnects, change the GTK (see [WUSB] |
| 421 | * section 6.2.11.2). */ | 397 | * section 6.2.11.2). */ |
| 422 | wusbhc_gtk_rekey(wusbhc); | 398 | wusbhc_gtk_rekey(wusbhc); |
| 423 | 399 | ||
| 424 | d_fnend(3, dev, "(wusbhc %p, port %p) = void\n", wusbhc, port); | ||
| 425 | /* The Wireless USB part has forgotten about the device already; now | 400 | /* The Wireless USB part has forgotten about the device already; now |
| 426 | * khubd's timer will pick up the disconnection and remove the USB | 401 | * khubd's timer will pick up the disconnection and remove the USB |
| 427 | * device from the system | 402 | * device from the system |
| @@ -429,39 +404,6 @@ static void __wusbhc_dev_disconnect(struct wusbhc *wusbhc, | |||
| 429 | } | 404 | } |
| 430 | 405 | ||
| 431 | /* | 406 | /* |
| 432 | * Authenticate a device into the WUSB Cluster | ||
| 433 | * | ||
| 434 | * Called from the Root Hub code (rh.c:wusbhc_rh_port_reset()) when | ||
| 435 | * asking for a reset on a port that is not enabled (ie: first connect | ||
| 436 | * on the port). | ||
| 437 | * | ||
| 438 | * Performs the 4way handshake to allow the device to comunicate w/ the | ||
| 439 | * WUSB Cluster securely; once done, issue a request to the device for | ||
| 440 | * it to change to address 0. | ||
| 441 | * | ||
| 442 | * This mimics the reset step of Wired USB that once resetting a | ||
| 443 | * device, leaves the port in enabled state and the dev with the | ||
| 444 | * default address (0). | ||
| 445 | * | ||
| 446 | * WUSB1.0[7.1.2] | ||
| 447 | * | ||
| 448 | * @port_idx: port where the change happened--This is the index into | ||
| 449 | * the wusbhc port array, not the USB port number. | ||
| 450 | */ | ||
| 451 | int wusbhc_devconnect_auth(struct wusbhc *wusbhc, u8 port_idx) | ||
| 452 | { | ||
| 453 | struct device *dev = wusbhc->dev; | ||
| 454 | struct wusb_port *port = wusb_port_by_idx(wusbhc, port_idx); | ||
| 455 | |||
| 456 | d_fnstart(3, dev, "(%p, %u)\n", wusbhc, port_idx); | ||
| 457 | port->status &= ~USB_PORT_STAT_RESET; | ||
| 458 | port->status |= USB_PORT_STAT_ENABLE; | ||
| 459 | port->change |= USB_PORT_STAT_C_RESET | USB_PORT_STAT_C_ENABLE; | ||
| 460 | d_fnend(3, dev, "(%p, %u) = 0\n", wusbhc, port_idx); | ||
| 461 | return 0; | ||
| 462 | } | ||
| 463 | |||
| 464 | /* | ||
| 465 | * Refresh the list of keep alives to emit in the MMC | 407 | * Refresh the list of keep alives to emit in the MMC |
| 466 | * | 408 | * |
| 467 | * Some devices don't respond to keep alives unless they've been | 409 | * Some devices don't respond to keep alives unless they've been |
| @@ -528,21 +470,15 @@ static void __wusbhc_keep_alive(struct wusbhc *wusbhc) | |||
| 528 | */ | 470 | */ |
| 529 | static void wusbhc_keep_alive_run(struct work_struct *ws) | 471 | static void wusbhc_keep_alive_run(struct work_struct *ws) |
| 530 | { | 472 | { |
| 531 | struct delayed_work *dw = | 473 | struct delayed_work *dw = container_of(ws, struct delayed_work, work); |
| 532 | container_of(ws, struct delayed_work, work); | 474 | struct wusbhc *wusbhc = container_of(dw, struct wusbhc, keep_alive_timer); |
| 533 | struct wusbhc *wusbhc = | 475 | |
| 534 | container_of(dw, struct wusbhc, keep_alive_timer); | 476 | mutex_lock(&wusbhc->mutex); |
| 535 | 477 | __wusbhc_keep_alive(wusbhc); | |
| 536 | d_fnstart(5, wusbhc->dev, "(wusbhc %p)\n", wusbhc); | 478 | mutex_unlock(&wusbhc->mutex); |
| 537 | if (wusbhc->active) { | 479 | |
| 538 | mutex_lock(&wusbhc->mutex); | 480 | queue_delayed_work(wusbd, &wusbhc->keep_alive_timer, |
| 539 | __wusbhc_keep_alive(wusbhc); | 481 | msecs_to_jiffies(wusbhc->trust_timeout / 2)); |
| 540 | mutex_unlock(&wusbhc->mutex); | ||
| 541 | queue_delayed_work(wusbd, &wusbhc->keep_alive_timer, | ||
| 542 | (wusbhc->trust_timeout * CONFIG_HZ)/1000/2); | ||
| 543 | } | ||
| 544 | d_fnend(5, wusbhc->dev, "(wusbhc %p) = void\n", wusbhc); | ||
| 545 | return; | ||
| 546 | } | 482 | } |
| 547 | 483 | ||
| 548 | /* | 484 | /* |
| @@ -585,10 +521,6 @@ static struct wusb_dev *wusbhc_find_dev_by_addr(struct wusbhc *wusbhc, u8 addr) | |||
| 585 | */ | 521 | */ |
| 586 | static void wusbhc_handle_dn_alive(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev) | 522 | static void wusbhc_handle_dn_alive(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev) |
| 587 | { | 523 | { |
| 588 | struct device *dev = wusbhc->dev; | ||
| 589 | |||
| 590 | d_printf(2, dev, "DN ALIVE: device 0x%02x pong\n", wusb_dev->addr); | ||
| 591 | |||
| 592 | mutex_lock(&wusbhc->mutex); | 524 | mutex_lock(&wusbhc->mutex); |
| 593 | wusb_dev->entry_ts = jiffies; | 525 | wusb_dev->entry_ts = jiffies; |
| 594 | __wusbhc_keep_alive(wusbhc); | 526 | __wusbhc_keep_alive(wusbhc); |
| @@ -621,11 +553,10 @@ static void wusbhc_handle_dn_connect(struct wusbhc *wusbhc, | |||
| 621 | "no-beacon" | 553 | "no-beacon" |
| 622 | }; | 554 | }; |
| 623 | 555 | ||
| 624 | d_fnstart(3, dev, "(%p, %p, %zu)\n", wusbhc, dn_hdr, size); | ||
| 625 | if (size < sizeof(*dnc)) { | 556 | if (size < sizeof(*dnc)) { |
| 626 | dev_err(dev, "DN CONNECT: short notification (%zu < %zu)\n", | 557 | dev_err(dev, "DN CONNECT: short notification (%zu < %zu)\n", |
| 627 | size, sizeof(*dnc)); | 558 | size, sizeof(*dnc)); |
| 628 | goto out; | 559 | return; |
| 629 | } | 560 | } |
| 630 | 561 | ||
| 631 | dnc = container_of(dn_hdr, struct wusb_dn_connect, hdr); | 562 | dnc = container_of(dn_hdr, struct wusb_dn_connect, hdr); |
| @@ -637,10 +568,6 @@ static void wusbhc_handle_dn_connect(struct wusbhc *wusbhc, | |||
| 637 | wusb_dn_connect_new_connection(dnc) ? "connect" : "reconnect"); | 568 | wusb_dn_connect_new_connection(dnc) ? "connect" : "reconnect"); |
| 638 | /* ACK the connect */ | 569 | /* ACK the connect */ |
| 639 | wusbhc_devconnect_ack(wusbhc, dnc, pr_cdid); | 570 | wusbhc_devconnect_ack(wusbhc, dnc, pr_cdid); |
| 640 | out: | ||
| 641 | d_fnend(3, dev, "(%p, %p, %zu) = void\n", | ||
| 642 | wusbhc, dn_hdr, size); | ||
| 643 | return; | ||
| 644 | } | 571 | } |
| 645 | 572 | ||
| 646 | /* | 573 | /* |
| @@ -662,60 +589,6 @@ static void wusbhc_handle_dn_disconnect(struct wusbhc *wusbhc, struct wusb_dev * | |||
| 662 | } | 589 | } |
| 663 | 590 | ||
| 664 | /* | 591 | /* |
| 665 | * Reset a WUSB device on a HWA | ||
| 666 | * | ||
| 667 | * @wusbhc | ||
| 668 | * @port_idx Index of the port where the device is | ||
| 669 | * | ||
| 670 | * In Wireless USB, a reset is more or less equivalent to a full | ||
| 671 | * disconnect; so we just do a full disconnect and send the device a | ||
| 672 | * Device Reset IE (WUSB1.0[7.5.11]) giving it a few millisecs (6 MMCs). | ||
| 673 | * | ||
| 674 | * @wusbhc should be refcounted and unlocked | ||
| 675 | */ | ||
| 676 | int wusbhc_dev_reset(struct wusbhc *wusbhc, u8 port_idx) | ||
| 677 | { | ||
| 678 | int result; | ||
| 679 | struct device *dev = wusbhc->dev; | ||
| 680 | struct wusb_dev *wusb_dev; | ||
| 681 | struct wuie_reset *ie; | ||
| 682 | |||
| 683 | d_fnstart(3, dev, "(%p, %u)\n", wusbhc, port_idx); | ||
| 684 | mutex_lock(&wusbhc->mutex); | ||
| 685 | result = 0; | ||
| 686 | wusb_dev = wusb_port_by_idx(wusbhc, port_idx)->wusb_dev; | ||
| 687 | if (wusb_dev == NULL) { | ||
| 688 | /* reset no device? ignore */ | ||
| 689 | dev_dbg(dev, "RESET: no device at port %u, ignoring\n", | ||
| 690 | port_idx); | ||
| 691 | goto error_unlock; | ||
| 692 | } | ||
| 693 | result = -ENOMEM; | ||
| 694 | ie = kzalloc(sizeof(*ie), GFP_KERNEL); | ||
| 695 | if (ie == NULL) | ||
| 696 | goto error_unlock; | ||
| 697 | ie->hdr.bLength = sizeof(ie->hdr) + sizeof(ie->CDID); | ||
| 698 | ie->hdr.bIEIdentifier = WUIE_ID_RESET_DEVICE; | ||
| 699 | ie->CDID = wusb_dev->cdid; | ||
| 700 | result = wusbhc_mmcie_set(wusbhc, 0xff, 6, &ie->hdr); | ||
| 701 | if (result < 0) { | ||
| 702 | dev_err(dev, "RESET: cant's set MMC: %d\n", result); | ||
| 703 | goto error_kfree; | ||
| 704 | } | ||
| 705 | __wusbhc_dev_disconnect(wusbhc, wusb_port_by_idx(wusbhc, port_idx)); | ||
| 706 | |||
| 707 | /* 120ms, hopefully 6 MMCs (FIXME) */ | ||
| 708 | msleep(120); | ||
| 709 | wusbhc_mmcie_rm(wusbhc, &ie->hdr); | ||
| 710 | error_kfree: | ||
| 711 | kfree(ie); | ||
| 712 | error_unlock: | ||
| 713 | mutex_unlock(&wusbhc->mutex); | ||
| 714 | d_fnend(3, dev, "(%p, %u) = %d\n", wusbhc, port_idx, result); | ||
| 715 | return result; | ||
| 716 | } | ||
| 717 | |||
| 718 | /* | ||
| 719 | * Handle a Device Notification coming a host | 592 | * Handle a Device Notification coming a host |
| 720 | * | 593 | * |
| 721 | * The Device Notification comes from a host (HWA, DWA or WHCI) | 594 | * The Device Notification comes from a host (HWA, DWA or WHCI) |
| @@ -735,19 +608,17 @@ void wusbhc_handle_dn(struct wusbhc *wusbhc, u8 srcaddr, | |||
| 735 | struct device *dev = wusbhc->dev; | 608 | struct device *dev = wusbhc->dev; |
| 736 | struct wusb_dev *wusb_dev; | 609 | struct wusb_dev *wusb_dev; |
| 737 | 610 | ||
| 738 | d_fnstart(3, dev, "(%p, %p)\n", wusbhc, dn_hdr); | ||
| 739 | |||
| 740 | if (size < sizeof(struct wusb_dn_hdr)) { | 611 | if (size < sizeof(struct wusb_dn_hdr)) { |
| 741 | dev_err(dev, "DN data shorter than DN header (%d < %d)\n", | 612 | dev_err(dev, "DN data shorter than DN header (%d < %d)\n", |
| 742 | (int)size, (int)sizeof(struct wusb_dn_hdr)); | 613 | (int)size, (int)sizeof(struct wusb_dn_hdr)); |
| 743 | goto out; | 614 | return; |
| 744 | } | 615 | } |
| 745 | 616 | ||
| 746 | wusb_dev = wusbhc_find_dev_by_addr(wusbhc, srcaddr); | 617 | wusb_dev = wusbhc_find_dev_by_addr(wusbhc, srcaddr); |
| 747 | if (wusb_dev == NULL && dn_hdr->bType != WUSB_DN_CONNECT) { | 618 | if (wusb_dev == NULL && dn_hdr->bType != WUSB_DN_CONNECT) { |
| 748 | dev_dbg(dev, "ignoring DN %d from unconnected device %02x\n", | 619 | dev_dbg(dev, "ignoring DN %d from unconnected device %02x\n", |
| 749 | dn_hdr->bType, srcaddr); | 620 | dn_hdr->bType, srcaddr); |
| 750 | goto out; | 621 | return; |
| 751 | } | 622 | } |
| 752 | 623 | ||
| 753 | switch (dn_hdr->bType) { | 624 | switch (dn_hdr->bType) { |
| @@ -772,9 +643,6 @@ void wusbhc_handle_dn(struct wusbhc *wusbhc, u8 srcaddr, | |||
| 772 | dev_warn(dev, "unknown DN %u (%d octets) from %u\n", | 643 | dev_warn(dev, "unknown DN %u (%d octets) from %u\n", |
| 773 | dn_hdr->bType, (int)size, srcaddr); | 644 | dn_hdr->bType, (int)size, srcaddr); |
| 774 | } | 645 | } |
| 775 | out: | ||
| 776 | d_fnend(3, dev, "(%p, %p) = void\n", wusbhc, dn_hdr); | ||
| 777 | return; | ||
| 778 | } | 646 | } |
| 779 | EXPORT_SYMBOL_GPL(wusbhc_handle_dn); | 647 | EXPORT_SYMBOL_GPL(wusbhc_handle_dn); |
| 780 | 648 | ||
| @@ -804,59 +672,30 @@ void __wusbhc_dev_disable(struct wusbhc *wusbhc, u8 port_idx) | |||
| 804 | struct wusb_dev *wusb_dev; | 672 | struct wusb_dev *wusb_dev; |
| 805 | struct wuie_disconnect *ie; | 673 | struct wuie_disconnect *ie; |
| 806 | 674 | ||
| 807 | d_fnstart(3, dev, "(%p, %u)\n", wusbhc, port_idx); | ||
| 808 | result = 0; | ||
| 809 | wusb_dev = wusb_port_by_idx(wusbhc, port_idx)->wusb_dev; | 675 | wusb_dev = wusb_port_by_idx(wusbhc, port_idx)->wusb_dev; |
| 810 | if (wusb_dev == NULL) { | 676 | if (wusb_dev == NULL) { |
| 811 | /* reset no device? ignore */ | 677 | /* reset no device? ignore */ |
| 812 | dev_dbg(dev, "DISCONNECT: no device at port %u, ignoring\n", | 678 | dev_dbg(dev, "DISCONNECT: no device at port %u, ignoring\n", |
| 813 | port_idx); | 679 | port_idx); |
| 814 | goto error; | 680 | return; |
| 815 | } | 681 | } |
| 816 | __wusbhc_dev_disconnect(wusbhc, wusb_port_by_idx(wusbhc, port_idx)); | 682 | __wusbhc_dev_disconnect(wusbhc, wusb_port_by_idx(wusbhc, port_idx)); |
| 817 | 683 | ||
| 818 | result = -ENOMEM; | ||
| 819 | ie = kzalloc(sizeof(*ie), GFP_KERNEL); | 684 | ie = kzalloc(sizeof(*ie), GFP_KERNEL); |
| 820 | if (ie == NULL) | 685 | if (ie == NULL) |
| 821 | goto error; | 686 | return; |
| 822 | ie->hdr.bLength = sizeof(*ie); | 687 | ie->hdr.bLength = sizeof(*ie); |
| 823 | ie->hdr.bIEIdentifier = WUIE_ID_DEVICE_DISCONNECT; | 688 | ie->hdr.bIEIdentifier = WUIE_ID_DEVICE_DISCONNECT; |
| 824 | ie->bDeviceAddress = wusb_dev->addr; | 689 | ie->bDeviceAddress = wusb_dev->addr; |
| 825 | result = wusbhc_mmcie_set(wusbhc, 0, 0, &ie->hdr); | 690 | result = wusbhc_mmcie_set(wusbhc, 0, 0, &ie->hdr); |
| 826 | if (result < 0) { | 691 | if (result < 0) |
| 827 | dev_err(dev, "DISCONNECT: can't set MMC: %d\n", result); | 692 | dev_err(dev, "DISCONNECT: can't set MMC: %d\n", result); |
| 828 | goto error_kfree; | 693 | else { |
| 694 | /* At least 6 MMCs, assuming at least 1 MMC per zone. */ | ||
| 695 | msleep(7*4); | ||
| 696 | wusbhc_mmcie_rm(wusbhc, &ie->hdr); | ||
| 829 | } | 697 | } |
| 830 | |||
| 831 | /* 120ms, hopefully 6 MMCs */ | ||
| 832 | msleep(100); | ||
| 833 | wusbhc_mmcie_rm(wusbhc, &ie->hdr); | ||
| 834 | error_kfree: | ||
| 835 | kfree(ie); | 698 | kfree(ie); |
| 836 | error: | ||
| 837 | d_fnend(3, dev, "(%p, %u) = %d\n", wusbhc, port_idx, result); | ||
| 838 | return; | ||
| 839 | } | ||
| 840 | |||
| 841 | static void wusb_cap_descr_printf(const unsigned level, struct device *dev, | ||
| 842 | const struct usb_wireless_cap_descriptor *wcd) | ||
| 843 | { | ||
| 844 | d_printf(level, dev, | ||
| 845 | "WUSB Capability Descriptor\n" | ||
| 846 | " bDevCapabilityType 0x%02x\n" | ||
| 847 | " bmAttributes 0x%02x\n" | ||
| 848 | " wPhyRates 0x%04x\n" | ||
| 849 | " bmTFITXPowerInfo 0x%02x\n" | ||
| 850 | " bmFFITXPowerInfo 0x%02x\n" | ||
| 851 | " bmBandGroup 0x%04x\n" | ||
| 852 | " bReserved 0x%02x\n", | ||
| 853 | wcd->bDevCapabilityType, | ||
| 854 | wcd->bmAttributes, | ||
| 855 | le16_to_cpu(wcd->wPHYRates), | ||
| 856 | wcd->bmTFITXPowerInfo, | ||
| 857 | wcd->bmFFITXPowerInfo, | ||
| 858 | wcd->bmBandGroup, | ||
| 859 | wcd->bReserved); | ||
| 860 | } | 699 | } |
| 861 | 700 | ||
| 862 | /* | 701 | /* |
| @@ -899,8 +738,6 @@ static int wusb_dev_bos_grok(struct usb_device *usb_dev, | |||
| 899 | } | 738 | } |
| 900 | cap_size = cap_hdr->bLength; | 739 | cap_size = cap_hdr->bLength; |
| 901 | cap_type = cap_hdr->bDevCapabilityType; | 740 | cap_type = cap_hdr->bDevCapabilityType; |
| 902 | d_printf(4, dev, "BOS Capability: 0x%02x (%zu bytes)\n", | ||
| 903 | cap_type, cap_size); | ||
| 904 | if (cap_size == 0) | 741 | if (cap_size == 0) |
| 905 | break; | 742 | break; |
| 906 | if (cap_size > top - itr) { | 743 | if (cap_size > top - itr) { |
| @@ -912,7 +749,6 @@ static int wusb_dev_bos_grok(struct usb_device *usb_dev, | |||
| 912 | result = -EBADF; | 749 | result = -EBADF; |
| 913 | goto error_bad_cap; | 750 | goto error_bad_cap; |
| 914 | } | 751 | } |
| 915 | d_dump(3, dev, itr, cap_size); | ||
| 916 | switch (cap_type) { | 752 | switch (cap_type) { |
| 917 | case USB_CAP_TYPE_WIRELESS_USB: | 753 | case USB_CAP_TYPE_WIRELESS_USB: |
| 918 | if (cap_size != sizeof(*wusb_dev->wusb_cap_descr)) | 754 | if (cap_size != sizeof(*wusb_dev->wusb_cap_descr)) |
| @@ -920,10 +756,8 @@ static int wusb_dev_bos_grok(struct usb_device *usb_dev, | |||
| 920 | "descriptor is %zu bytes vs %zu " | 756 | "descriptor is %zu bytes vs %zu " |
| 921 | "needed\n", cap_size, | 757 | "needed\n", cap_size, |
| 922 | sizeof(*wusb_dev->wusb_cap_descr)); | 758 | sizeof(*wusb_dev->wusb_cap_descr)); |
| 923 | else { | 759 | else |
| 924 | wusb_dev->wusb_cap_descr = itr; | 760 | wusb_dev->wusb_cap_descr = itr; |
| 925 | wusb_cap_descr_printf(3, dev, itr); | ||
| 926 | } | ||
| 927 | break; | 761 | break; |
| 928 | default: | 762 | default: |
| 929 | dev_err(dev, "BUG? Unknown BOS capability 0x%02x " | 763 | dev_err(dev, "BUG? Unknown BOS capability 0x%02x " |
| @@ -988,9 +822,7 @@ static int wusb_dev_bos_add(struct usb_device *usb_dev, | |||
| 988 | "%zu bytes): %zd\n", desc_size, result); | 822 | "%zu bytes): %zd\n", desc_size, result); |
| 989 | goto error_get_descriptor; | 823 | goto error_get_descriptor; |
| 990 | } | 824 | } |
| 991 | d_printf(2, dev, "Got BOS descriptor %zd bytes, %u capabilities\n", | 825 | |
| 992 | result, bos->bNumDeviceCaps); | ||
| 993 | d_dump(2, dev, bos, result); | ||
| 994 | result = wusb_dev_bos_grok(usb_dev, wusb_dev, bos, result); | 826 | result = wusb_dev_bos_grok(usb_dev, wusb_dev, bos, result); |
| 995 | if (result < 0) | 827 | if (result < 0) |
| 996 | goto error_bad_bos; | 828 | goto error_bad_bos; |
| @@ -1056,8 +888,6 @@ static void wusb_dev_add_ncb(struct usb_device *usb_dev) | |||
| 1056 | if (usb_dev->wusb == 0 || usb_dev->devnum == 1) | 888 | if (usb_dev->wusb == 0 || usb_dev->devnum == 1) |
| 1057 | return; /* skip non wusb and wusb RHs */ | 889 | return; /* skip non wusb and wusb RHs */ |
| 1058 | 890 | ||
| 1059 | d_fnstart(3, dev, "(usb_dev %p)\n", usb_dev); | ||
| 1060 | |||
| 1061 | wusbhc = wusbhc_get_by_usb_dev(usb_dev); | 891 | wusbhc = wusbhc_get_by_usb_dev(usb_dev); |
| 1062 | if (wusbhc == NULL) | 892 | if (wusbhc == NULL) |
| 1063 | goto error_nodev; | 893 | goto error_nodev; |
| @@ -1087,7 +917,6 @@ out: | |||
| 1087 | wusb_dev_put(wusb_dev); | 917 | wusb_dev_put(wusb_dev); |
| 1088 | wusbhc_put(wusbhc); | 918 | wusbhc_put(wusbhc); |
| 1089 | error_nodev: | 919 | error_nodev: |
| 1090 | d_fnend(3, dev, "(usb_dev %p) = void\n", usb_dev); | ||
| 1091 | return; | 920 | return; |
| 1092 | 921 | ||
| 1093 | wusb_dev_sysfs_rm(wusb_dev); | 922 | wusb_dev_sysfs_rm(wusb_dev); |
| @@ -1174,11 +1003,10 @@ EXPORT_SYMBOL_GPL(__wusb_dev_get_by_usb_dev); | |||
| 1174 | 1003 | ||
| 1175 | void wusb_dev_destroy(struct kref *_wusb_dev) | 1004 | void wusb_dev_destroy(struct kref *_wusb_dev) |
| 1176 | { | 1005 | { |
| 1177 | struct wusb_dev *wusb_dev | 1006 | struct wusb_dev *wusb_dev = container_of(_wusb_dev, struct wusb_dev, refcnt); |
| 1178 | = container_of(_wusb_dev, struct wusb_dev, refcnt); | 1007 | |
| 1179 | list_del_init(&wusb_dev->cack_node); | 1008 | list_del_init(&wusb_dev->cack_node); |
| 1180 | wusb_dev_free(wusb_dev); | 1009 | wusb_dev_free(wusb_dev); |
| 1181 | d_fnend(1, NULL, "%s (wusb_dev %p) = void\n", __func__, wusb_dev); | ||
| 1182 | } | 1010 | } |
| 1183 | EXPORT_SYMBOL_GPL(wusb_dev_destroy); | 1011 | EXPORT_SYMBOL_GPL(wusb_dev_destroy); |
| 1184 | 1012 | ||
| @@ -1190,8 +1018,6 @@ EXPORT_SYMBOL_GPL(wusb_dev_destroy); | |||
| 1190 | */ | 1018 | */ |
| 1191 | int wusbhc_devconnect_create(struct wusbhc *wusbhc) | 1019 | int wusbhc_devconnect_create(struct wusbhc *wusbhc) |
| 1192 | { | 1020 | { |
| 1193 | d_fnstart(3, wusbhc->dev, "(wusbhc %p)\n", wusbhc); | ||
| 1194 | |||
| 1195 | wusbhc->keep_alive_ie.hdr.bIEIdentifier = WUIE_ID_KEEP_ALIVE; | 1021 | wusbhc->keep_alive_ie.hdr.bIEIdentifier = WUIE_ID_KEEP_ALIVE; |
| 1196 | wusbhc->keep_alive_ie.hdr.bLength = sizeof(wusbhc->keep_alive_ie.hdr); | 1022 | wusbhc->keep_alive_ie.hdr.bLength = sizeof(wusbhc->keep_alive_ie.hdr); |
| 1197 | INIT_DELAYED_WORK(&wusbhc->keep_alive_timer, wusbhc_keep_alive_run); | 1023 | INIT_DELAYED_WORK(&wusbhc->keep_alive_timer, wusbhc_keep_alive_run); |
| @@ -1200,7 +1026,6 @@ int wusbhc_devconnect_create(struct wusbhc *wusbhc) | |||
| 1200 | wusbhc->cack_ie.hdr.bLength = sizeof(wusbhc->cack_ie.hdr); | 1026 | wusbhc->cack_ie.hdr.bLength = sizeof(wusbhc->cack_ie.hdr); |
| 1201 | INIT_LIST_HEAD(&wusbhc->cack_list); | 1027 | INIT_LIST_HEAD(&wusbhc->cack_list); |
| 1202 | 1028 | ||
| 1203 | d_fnend(3, wusbhc->dev, "(wusbhc %p) = void\n", wusbhc); | ||
| 1204 | return 0; | 1029 | return 0; |
| 1205 | } | 1030 | } |
| 1206 | 1031 | ||
| @@ -1209,8 +1034,7 @@ int wusbhc_devconnect_create(struct wusbhc *wusbhc) | |||
| 1209 | */ | 1034 | */ |
| 1210 | void wusbhc_devconnect_destroy(struct wusbhc *wusbhc) | 1035 | void wusbhc_devconnect_destroy(struct wusbhc *wusbhc) |
| 1211 | { | 1036 | { |
| 1212 | d_fnstart(3, wusbhc->dev, "(wusbhc %p)\n", wusbhc); | 1037 | /* no op */ |
| 1213 | d_fnend(3, wusbhc->dev, "(wusbhc %p) = void\n", wusbhc); | ||
| 1214 | } | 1038 | } |
| 1215 | 1039 | ||
| 1216 | /* | 1040 | /* |
| @@ -1222,8 +1046,7 @@ void wusbhc_devconnect_destroy(struct wusbhc *wusbhc) | |||
| 1222 | * FIXME: This also enables the keep alives but this is not necessary | 1046 | * FIXME: This also enables the keep alives but this is not necessary |
| 1223 | * until there are connected and authenticated devices. | 1047 | * until there are connected and authenticated devices. |
| 1224 | */ | 1048 | */ |
| 1225 | int wusbhc_devconnect_start(struct wusbhc *wusbhc, | 1049 | int wusbhc_devconnect_start(struct wusbhc *wusbhc) |
| 1226 | const struct wusb_ckhdid *chid) | ||
| 1227 | { | 1050 | { |
| 1228 | struct device *dev = wusbhc->dev; | 1051 | struct device *dev = wusbhc->dev; |
| 1229 | struct wuie_host_info *hi; | 1052 | struct wuie_host_info *hi; |
| @@ -1236,7 +1059,7 @@ int wusbhc_devconnect_start(struct wusbhc *wusbhc, | |||
| 1236 | hi->hdr.bLength = sizeof(*hi); | 1059 | hi->hdr.bLength = sizeof(*hi); |
| 1237 | hi->hdr.bIEIdentifier = WUIE_ID_HOST_INFO; | 1060 | hi->hdr.bIEIdentifier = WUIE_ID_HOST_INFO; |
| 1238 | hi->attributes = cpu_to_le16((wusbhc->rsv->stream << 3) | WUIE_HI_CAP_ALL); | 1061 | hi->attributes = cpu_to_le16((wusbhc->rsv->stream << 3) | WUIE_HI_CAP_ALL); |
| 1239 | hi->CHID = *chid; | 1062 | hi->CHID = wusbhc->chid; |
| 1240 | result = wusbhc_mmcie_set(wusbhc, 0, 0, &hi->hdr); | 1063 | result = wusbhc_mmcie_set(wusbhc, 0, 0, &hi->hdr); |
| 1241 | if (result < 0) { | 1064 | if (result < 0) { |
| 1242 | dev_err(dev, "Cannot add Host Info MMCIE: %d\n", result); | 1065 | dev_err(dev, "Cannot add Host Info MMCIE: %d\n", result); |
diff --git a/drivers/usb/wusbcore/mmc.c b/drivers/usb/wusbcore/mmc.c index cfa77a01ceb..3b52161e6e9 100644 --- a/drivers/usb/wusbcore/mmc.c +++ b/drivers/usb/wusbcore/mmc.c | |||
| @@ -159,15 +159,35 @@ found: | |||
| 159 | } | 159 | } |
| 160 | EXPORT_SYMBOL_GPL(wusbhc_mmcie_rm); | 160 | EXPORT_SYMBOL_GPL(wusbhc_mmcie_rm); |
| 161 | 161 | ||
| 162 | static int wusbhc_mmc_start(struct wusbhc *wusbhc) | ||
| 163 | { | ||
| 164 | int ret; | ||
| 165 | |||
| 166 | mutex_lock(&wusbhc->mutex); | ||
| 167 | ret = wusbhc->start(wusbhc); | ||
| 168 | if (ret >= 0) | ||
| 169 | wusbhc->active = 1; | ||
| 170 | mutex_unlock(&wusbhc->mutex); | ||
| 171 | |||
| 172 | return ret; | ||
| 173 | } | ||
| 174 | |||
| 175 | static void wusbhc_mmc_stop(struct wusbhc *wusbhc) | ||
| 176 | { | ||
| 177 | mutex_lock(&wusbhc->mutex); | ||
| 178 | wusbhc->active = 0; | ||
| 179 | wusbhc->stop(wusbhc, WUSB_CHANNEL_STOP_DELAY_MS); | ||
| 180 | mutex_unlock(&wusbhc->mutex); | ||
| 181 | } | ||
| 182 | |||
| 162 | /* | 183 | /* |
| 163 | * wusbhc_start - start transmitting MMCs and accepting connections | 184 | * wusbhc_start - start transmitting MMCs and accepting connections |
| 164 | * @wusbhc: the HC to start | 185 | * @wusbhc: the HC to start |
| 165 | * @chid: the CHID to use for this host | ||
| 166 | * | 186 | * |
| 167 | * Establishes a cluster reservation, enables device connections, and | 187 | * Establishes a cluster reservation, enables device connections, and |
| 168 | * starts MMCs with appropriate DNTS parameters. | 188 | * starts MMCs with appropriate DNTS parameters. |
| 169 | */ | 189 | */ |
| 170 | int wusbhc_start(struct wusbhc *wusbhc, const struct wusb_ckhdid *chid) | 190 | int wusbhc_start(struct wusbhc *wusbhc) |
| 171 | { | 191 | { |
| 172 | int result; | 192 | int result; |
| 173 | struct device *dev = wusbhc->dev; | 193 | struct device *dev = wusbhc->dev; |
| @@ -181,7 +201,7 @@ int wusbhc_start(struct wusbhc *wusbhc, const struct wusb_ckhdid *chid) | |||
| 181 | goto error_rsv_establish; | 201 | goto error_rsv_establish; |
| 182 | } | 202 | } |
| 183 | 203 | ||
| 184 | result = wusbhc_devconnect_start(wusbhc, chid); | 204 | result = wusbhc_devconnect_start(wusbhc); |
| 185 | if (result < 0) { | 205 | if (result < 0) { |
| 186 | dev_err(dev, "error enabling device connections: %d\n", result); | 206 | dev_err(dev, "error enabling device connections: %d\n", result); |
| 187 | goto error_devconnect_start; | 207 | goto error_devconnect_start; |
| @@ -199,12 +219,12 @@ int wusbhc_start(struct wusbhc *wusbhc, const struct wusb_ckhdid *chid) | |||
| 199 | dev_err(dev, "Cannot set DNTS parameters: %d\n", result); | 219 | dev_err(dev, "Cannot set DNTS parameters: %d\n", result); |
| 200 | goto error_set_num_dnts; | 220 | goto error_set_num_dnts; |
| 201 | } | 221 | } |
| 202 | result = wusbhc->start(wusbhc); | 222 | result = wusbhc_mmc_start(wusbhc); |
| 203 | if (result < 0) { | 223 | if (result < 0) { |
| 204 | dev_err(dev, "error starting wusbch: %d\n", result); | 224 | dev_err(dev, "error starting wusbch: %d\n", result); |
| 205 | goto error_wusbhc_start; | 225 | goto error_wusbhc_start; |
| 206 | } | 226 | } |
| 207 | wusbhc->active = 1; | 227 | |
| 208 | return 0; | 228 | return 0; |
| 209 | 229 | ||
| 210 | error_wusbhc_start: | 230 | error_wusbhc_start: |
| @@ -219,76 +239,17 @@ error_rsv_establish: | |||
| 219 | } | 239 | } |
| 220 | 240 | ||
| 221 | /* | 241 | /* |
| 222 | * Disconnect all from the WUSB Channel | ||
| 223 | * | ||
| 224 | * Send a Host Disconnect IE in the MMC, wait, don't send it any more | ||
| 225 | */ | ||
| 226 | static int __wusbhc_host_disconnect_ie(struct wusbhc *wusbhc) | ||
| 227 | { | ||
| 228 | int result = -ENOMEM; | ||
| 229 | struct wuie_host_disconnect *host_disconnect_ie; | ||
| 230 | might_sleep(); | ||
| 231 | host_disconnect_ie = kmalloc(sizeof(*host_disconnect_ie), GFP_KERNEL); | ||
| 232 | if (host_disconnect_ie == NULL) | ||
| 233 | goto error_alloc; | ||
| 234 | host_disconnect_ie->hdr.bLength = sizeof(*host_disconnect_ie); | ||
| 235 | host_disconnect_ie->hdr.bIEIdentifier = WUIE_ID_HOST_DISCONNECT; | ||
| 236 | result = wusbhc_mmcie_set(wusbhc, 0, 0, &host_disconnect_ie->hdr); | ||
| 237 | if (result < 0) | ||
| 238 | goto error_mmcie_set; | ||
| 239 | |||
| 240 | /* WUSB1.0[8.5.3.1 & 7.5.2] */ | ||
| 241 | msleep(100); | ||
| 242 | wusbhc_mmcie_rm(wusbhc, &host_disconnect_ie->hdr); | ||
| 243 | error_mmcie_set: | ||
| 244 | kfree(host_disconnect_ie); | ||
| 245 | error_alloc: | ||
| 246 | return result; | ||
| 247 | } | ||
| 248 | |||
| 249 | /* | ||
| 250 | * wusbhc_stop - stop transmitting MMCs | 242 | * wusbhc_stop - stop transmitting MMCs |
| 251 | * @wusbhc: the HC to stop | 243 | * @wusbhc: the HC to stop |
| 252 | * | 244 | * |
| 253 | * Send a Host Disconnect IE, wait, remove all the MMCs (stop sending MMCs). | 245 | * Stops the WUSB channel and removes the cluster reservation. |
| 254 | * | ||
| 255 | * If we can't allocate a Host Stop IE, screw it, we don't notify the | ||
| 256 | * devices we are disconnecting... | ||
| 257 | */ | 246 | */ |
| 258 | void wusbhc_stop(struct wusbhc *wusbhc) | 247 | void wusbhc_stop(struct wusbhc *wusbhc) |
| 259 | { | 248 | { |
| 260 | if (wusbhc->active) { | 249 | wusbhc_mmc_stop(wusbhc); |
| 261 | wusbhc->active = 0; | 250 | wusbhc_sec_stop(wusbhc); |
| 262 | wusbhc->stop(wusbhc); | 251 | wusbhc_devconnect_stop(wusbhc); |
| 263 | wusbhc_sec_stop(wusbhc); | 252 | wusbhc_rsv_terminate(wusbhc); |
| 264 | __wusbhc_host_disconnect_ie(wusbhc); | ||
| 265 | wusbhc_devconnect_stop(wusbhc); | ||
| 266 | wusbhc_rsv_terminate(wusbhc); | ||
| 267 | } | ||
| 268 | } | ||
| 269 | EXPORT_SYMBOL_GPL(wusbhc_stop); | ||
| 270 | |||
| 271 | /* | ||
| 272 | * Change the CHID in a WUSB Channel | ||
| 273 | * | ||
| 274 | * If it is just a new CHID, send a Host Disconnect IE and then change | ||
| 275 | * the CHID IE. | ||
| 276 | */ | ||
| 277 | static int __wusbhc_chid_change(struct wusbhc *wusbhc, | ||
| 278 | const struct wusb_ckhdid *chid) | ||
| 279 | { | ||
| 280 | int result = -ENOSYS; | ||
| 281 | struct device *dev = wusbhc->dev; | ||
| 282 | dev_err(dev, "%s() not implemented yet\n", __func__); | ||
| 283 | return result; | ||
| 284 | |||
| 285 | BUG_ON(wusbhc->wuie_host_info == NULL); | ||
| 286 | __wusbhc_host_disconnect_ie(wusbhc); | ||
| 287 | wusbhc->wuie_host_info->CHID = *chid; | ||
| 288 | result = wusbhc_mmcie_set(wusbhc, 0, 0, &wusbhc->wuie_host_info->hdr); | ||
| 289 | if (result < 0) | ||
| 290 | dev_err(dev, "Can't update Host Info WUSB IE: %d\n", result); | ||
| 291 | return result; | ||
| 292 | } | 253 | } |
| 293 | 254 | ||
| 294 | /* | 255 | /* |
| @@ -306,16 +267,19 @@ int wusbhc_chid_set(struct wusbhc *wusbhc, const struct wusb_ckhdid *chid) | |||
| 306 | chid = NULL; | 267 | chid = NULL; |
| 307 | 268 | ||
| 308 | mutex_lock(&wusbhc->mutex); | 269 | mutex_lock(&wusbhc->mutex); |
| 309 | if (wusbhc->active) { | 270 | if (chid) { |
| 310 | if (chid) | 271 | if (wusbhc->active) { |
| 311 | result = __wusbhc_chid_change(wusbhc, chid); | 272 | mutex_unlock(&wusbhc->mutex); |
| 312 | else | 273 | return -EBUSY; |
| 313 | wusbhc_stop(wusbhc); | 274 | } |
| 314 | } else { | 275 | wusbhc->chid = *chid; |
| 315 | if (chid) | ||
| 316 | wusbhc_start(wusbhc, chid); | ||
| 317 | } | 276 | } |
| 318 | mutex_unlock(&wusbhc->mutex); | 277 | mutex_unlock(&wusbhc->mutex); |
| 278 | |||
| 279 | if (chid) | ||
| 280 | result = uwb_radio_start(&wusbhc->pal); | ||
| 281 | else | ||
| 282 | uwb_radio_stop(&wusbhc->pal); | ||
| 319 | return result; | 283 | return result; |
| 320 | } | 284 | } |
| 321 | EXPORT_SYMBOL_GPL(wusbhc_chid_set); | 285 | EXPORT_SYMBOL_GPL(wusbhc_chid_set); |
diff --git a/drivers/usb/wusbcore/pal.c b/drivers/usb/wusbcore/pal.c index 7cc51e9905c..d0b172c5ecc 100644 --- a/drivers/usb/wusbcore/pal.c +++ b/drivers/usb/wusbcore/pal.c | |||
| @@ -18,6 +18,16 @@ | |||
| 18 | */ | 18 | */ |
| 19 | #include "wusbhc.h" | 19 | #include "wusbhc.h" |
| 20 | 20 | ||
| 21 | static void wusbhc_channel_changed(struct uwb_pal *pal, int channel) | ||
| 22 | { | ||
| 23 | struct wusbhc *wusbhc = container_of(pal, struct wusbhc, pal); | ||
| 24 | |||
| 25 | if (channel < 0) | ||
| 26 | wusbhc_stop(wusbhc); | ||
| 27 | else | ||
| 28 | wusbhc_start(wusbhc); | ||
| 29 | } | ||
| 30 | |||
| 21 | /** | 31 | /** |
| 22 | * wusbhc_pal_register - register the WUSB HC as a UWB PAL | 32 | * wusbhc_pal_register - register the WUSB HC as a UWB PAL |
| 23 | * @wusbhc: the WUSB HC | 33 | * @wusbhc: the WUSB HC |
| @@ -28,8 +38,10 @@ int wusbhc_pal_register(struct wusbhc *wusbhc) | |||
| 28 | 38 | ||
| 29 | wusbhc->pal.name = "wusbhc"; | 39 | wusbhc->pal.name = "wusbhc"; |
| 30 | wusbhc->pal.device = wusbhc->usb_hcd.self.controller; | 40 | wusbhc->pal.device = wusbhc->usb_hcd.self.controller; |
| 41 | wusbhc->pal.rc = wusbhc->uwb_rc; | ||
| 42 | wusbhc->pal.channel_changed = wusbhc_channel_changed; | ||
| 31 | 43 | ||
| 32 | return uwb_pal_register(wusbhc->uwb_rc, &wusbhc->pal); | 44 | return uwb_pal_register(&wusbhc->pal); |
| 33 | } | 45 | } |
| 34 | 46 | ||
| 35 | /** | 47 | /** |
| @@ -38,5 +50,5 @@ int wusbhc_pal_register(struct wusbhc *wusbhc) | |||
| 38 | */ | 50 | */ |
| 39 | void wusbhc_pal_unregister(struct wusbhc *wusbhc) | 51 | void wusbhc_pal_unregister(struct wusbhc *wusbhc) |
| 40 | { | 52 | { |
| 41 | uwb_pal_unregister(wusbhc->uwb_rc, &wusbhc->pal); | 53 | uwb_pal_unregister(&wusbhc->pal); |
| 42 | } | 54 | } |
diff --git a/drivers/usb/wusbcore/reservation.c b/drivers/usb/wusbcore/reservation.c index fc63e77ded2..4ed97360c04 100644 --- a/drivers/usb/wusbcore/reservation.c +++ b/drivers/usb/wusbcore/reservation.c | |||
| @@ -48,18 +48,19 @@ static void wusbhc_rsv_complete_cb(struct uwb_rsv *rsv) | |||
| 48 | { | 48 | { |
| 49 | struct wusbhc *wusbhc = rsv->pal_priv; | 49 | struct wusbhc *wusbhc = rsv->pal_priv; |
| 50 | struct device *dev = wusbhc->dev; | 50 | struct device *dev = wusbhc->dev; |
| 51 | struct uwb_mas_bm mas; | ||
| 51 | char buf[72]; | 52 | char buf[72]; |
| 52 | 53 | ||
| 53 | switch (rsv->state) { | 54 | switch (rsv->state) { |
| 54 | case UWB_RSV_STATE_O_ESTABLISHED: | 55 | case UWB_RSV_STATE_O_ESTABLISHED: |
| 55 | bitmap_scnprintf(buf, sizeof(buf), rsv->mas.bm, UWB_NUM_MAS); | 56 | uwb_rsv_get_usable_mas(rsv, &mas); |
| 57 | bitmap_scnprintf(buf, sizeof(buf), mas.bm, UWB_NUM_MAS); | ||
| 56 | dev_dbg(dev, "established reservation: %s\n", buf); | 58 | dev_dbg(dev, "established reservation: %s\n", buf); |
| 57 | wusbhc_bwa_set(wusbhc, rsv->stream, &rsv->mas); | 59 | wusbhc_bwa_set(wusbhc, rsv->stream, &mas); |
| 58 | break; | 60 | break; |
| 59 | case UWB_RSV_STATE_NONE: | 61 | case UWB_RSV_STATE_NONE: |
| 60 | dev_dbg(dev, "removed reservation\n"); | 62 | dev_dbg(dev, "removed reservation\n"); |
| 61 | wusbhc_bwa_set(wusbhc, 0, NULL); | 63 | wusbhc_bwa_set(wusbhc, 0, NULL); |
| 62 | wusbhc->rsv = NULL; | ||
| 63 | break; | 64 | break; |
| 64 | default: | 65 | default: |
| 65 | dev_dbg(dev, "unexpected reservation state: %d\n", rsv->state); | 66 | dev_dbg(dev, "unexpected reservation state: %d\n", rsv->state); |
| @@ -86,13 +87,12 @@ int wusbhc_rsv_establish(struct wusbhc *wusbhc) | |||
| 86 | bcid.data[0] = wusbhc->cluster_id; | 87 | bcid.data[0] = wusbhc->cluster_id; |
| 87 | bcid.data[1] = 0; | 88 | bcid.data[1] = 0; |
| 88 | 89 | ||
| 89 | rsv->owner = &rc->uwb_dev; | ||
| 90 | rsv->target.type = UWB_RSV_TARGET_DEVADDR; | 90 | rsv->target.type = UWB_RSV_TARGET_DEVADDR; |
| 91 | rsv->target.devaddr = bcid; | 91 | rsv->target.devaddr = bcid; |
| 92 | rsv->type = UWB_DRP_TYPE_PRIVATE; | 92 | rsv->type = UWB_DRP_TYPE_PRIVATE; |
| 93 | rsv->max_mas = 256; | 93 | rsv->max_mas = 256; /* try to get as much as possible */ |
| 94 | rsv->min_mas = 16; /* one MAS per zone? */ | 94 | rsv->min_mas = 15; /* one MAS per zone */ |
| 95 | rsv->sparsity = 16; /* at least one MAS in each zone? */ | 95 | rsv->max_interval = 1; /* max latency is one zone */ |
| 96 | rsv->is_multicast = true; | 96 | rsv->is_multicast = true; |
| 97 | 97 | ||
| 98 | ret = uwb_rsv_establish(rsv); | 98 | ret = uwb_rsv_establish(rsv); |
| @@ -105,11 +105,14 @@ int wusbhc_rsv_establish(struct wusbhc *wusbhc) | |||
| 105 | 105 | ||
| 106 | 106 | ||
| 107 | /** | 107 | /** |
| 108 | * wusbhc_rsv_terminate - terminate any cluster reservation | 108 | * wusbhc_rsv_terminate - terminate the cluster reservation |
| 109 | * @wusbhc: the WUSB host whose reservation is to be terminated | 109 | * @wusbhc: the WUSB host whose reservation is to be terminated |
| 110 | */ | 110 | */ |
| 111 | void wusbhc_rsv_terminate(struct wusbhc *wusbhc) | 111 | void wusbhc_rsv_terminate(struct wusbhc *wusbhc) |
| 112 | { | 112 | { |
| 113 | if (wusbhc->rsv) | 113 | if (wusbhc->rsv) { |
| 114 | uwb_rsv_terminate(wusbhc->rsv); | 114 | uwb_rsv_terminate(wusbhc->rsv); |
| 115 | uwb_rsv_destroy(wusbhc->rsv); | ||
| 116 | wusbhc->rsv = NULL; | ||
| 117 | } | ||
| 115 | } | 118 | } |
diff --git a/drivers/usb/wusbcore/rh.c b/drivers/usb/wusbcore/rh.c index 267a6432510..95c6fa3bf6b 100644 --- a/drivers/usb/wusbcore/rh.c +++ b/drivers/usb/wusbcore/rh.c | |||
| @@ -71,19 +71,20 @@ | |||
| 71 | */ | 71 | */ |
| 72 | #include "wusbhc.h" | 72 | #include "wusbhc.h" |
| 73 | 73 | ||
| 74 | #define D_LOCAL 0 | ||
| 75 | #include <linux/uwb/debug.h> | ||
| 76 | |||
| 77 | /* | 74 | /* |
| 78 | * Reset a fake port | 75 | * Reset a fake port |
| 79 | * | 76 | * |
| 80 | * This can be called to reset a port from any other state or to reset | 77 | * Using a Reset Device IE is too heavyweight as it causes the device |
| 81 | * it when connecting. In Wireless USB they are different; when doing | 78 | * to enter the UnConnected state and leave the cluster, this can mean |
| 82 | * a new connect that involves going over the authentication. When | 79 | * that when the device reconnects it is connected to a different fake |
| 83 | * just reseting, its a different story. | 80 | * port. |
| 81 | * | ||
| 82 | * Instead, reset authenticated devices with a SetAddress(0), followed | ||
| 83 | * by a SetAddresss(AuthAddr). | ||
| 84 | * | 84 | * |
| 85 | * The Linux USB stack resets a port twice before it considers it | 85 | * For unauthenticated devices just pretend to reset but do nothing. |
| 86 | * enabled, so we have to detect and ignore that. | 86 | * If the device initialization continues to fail it will eventually |
| 87 | * time out after TrustTimeout and enter the UnConnected state. | ||
| 87 | * | 88 | * |
| 88 | * @wusbhc is assumed referenced and @wusbhc->mutex unlocked. | 89 | * @wusbhc is assumed referenced and @wusbhc->mutex unlocked. |
| 89 | * | 90 | * |
| @@ -97,20 +98,20 @@ static int wusbhc_rh_port_reset(struct wusbhc *wusbhc, u8 port_idx) | |||
| 97 | { | 98 | { |
| 98 | int result = 0; | 99 | int result = 0; |
| 99 | struct wusb_port *port = wusb_port_by_idx(wusbhc, port_idx); | 100 | struct wusb_port *port = wusb_port_by_idx(wusbhc, port_idx); |
| 101 | struct wusb_dev *wusb_dev = port->wusb_dev; | ||
| 100 | 102 | ||
| 101 | d_fnstart(3, wusbhc->dev, "(wusbhc %p port_idx %u)\n", | 103 | port->status |= USB_PORT_STAT_RESET; |
| 102 | wusbhc, port_idx); | 104 | port->change |= USB_PORT_STAT_C_RESET; |
| 103 | if (port->reset_count == 0) { | 105 | |
| 104 | wusbhc_devconnect_auth(wusbhc, port_idx); | 106 | if (wusb_dev->addr & WUSB_DEV_ADDR_UNAUTH) |
| 105 | port->reset_count++; | 107 | result = 0; |
| 106 | } else if (port->reset_count == 1) | ||
| 107 | /* see header */ | ||
| 108 | d_printf(2, wusbhc->dev, "Ignoring second reset on port_idx " | ||
| 109 | "%u\n", port_idx); | ||
| 110 | else | 108 | else |
| 111 | result = wusbhc_dev_reset(wusbhc, port_idx); | 109 | result = wusb_dev_update_address(wusbhc, wusb_dev); |
| 112 | d_fnend(3, wusbhc->dev, "(wusbhc %p port_idx %u) = %d\n", | 110 | |
| 113 | wusbhc, port_idx, result); | 111 | port->status &= ~USB_PORT_STAT_RESET; |
| 112 | port->status |= USB_PORT_STAT_ENABLE; | ||
| 113 | port->change |= USB_PORT_STAT_C_RESET | USB_PORT_STAT_C_ENABLE; | ||
| 114 | |||
| 114 | return result; | 115 | return result; |
| 115 | } | 116 | } |
| 116 | 117 | ||
| @@ -138,7 +139,6 @@ int wusbhc_rh_status_data(struct usb_hcd *usb_hcd, char *_buf) | |||
| 138 | size_t cnt, size; | 139 | size_t cnt, size; |
| 139 | unsigned long *buf = (unsigned long *) _buf; | 140 | unsigned long *buf = (unsigned long *) _buf; |
| 140 | 141 | ||
| 141 | d_fnstart(1, wusbhc->dev, "(wusbhc %p)\n", wusbhc); | ||
| 142 | /* WE DON'T LOCK, see comment */ | 142 | /* WE DON'T LOCK, see comment */ |
| 143 | size = wusbhc->ports_max + 1 /* hub bit */; | 143 | size = wusbhc->ports_max + 1 /* hub bit */; |
| 144 | size = (size + 8 - 1) / 8; /* round to bytes */ | 144 | size = (size + 8 - 1) / 8; /* round to bytes */ |
| @@ -147,8 +147,6 @@ int wusbhc_rh_status_data(struct usb_hcd *usb_hcd, char *_buf) | |||
| 147 | set_bit(cnt + 1, buf); | 147 | set_bit(cnt + 1, buf); |
| 148 | else | 148 | else |
| 149 | clear_bit(cnt + 1, buf); | 149 | clear_bit(cnt + 1, buf); |
| 150 | d_fnend(1, wusbhc->dev, "(wusbhc %p) %u, buffer:\n", wusbhc, (int)size); | ||
| 151 | d_dump(1, wusbhc->dev, _buf, size); | ||
| 152 | return size; | 150 | return size; |
| 153 | } | 151 | } |
| 154 | EXPORT_SYMBOL_GPL(wusbhc_rh_status_data); | 152 | EXPORT_SYMBOL_GPL(wusbhc_rh_status_data); |
| @@ -197,9 +195,7 @@ static int wusbhc_rh_get_hub_descr(struct wusbhc *wusbhc, u16 wValue, | |||
| 197 | static int wusbhc_rh_clear_hub_feat(struct wusbhc *wusbhc, u16 feature) | 195 | static int wusbhc_rh_clear_hub_feat(struct wusbhc *wusbhc, u16 feature) |
| 198 | { | 196 | { |
| 199 | int result; | 197 | int result; |
| 200 | struct device *dev = wusbhc->dev; | ||
| 201 | 198 | ||
| 202 | d_fnstart(4, dev, "(%p, feature 0x%04u)\n", wusbhc, feature); | ||
| 203 | switch (feature) { | 199 | switch (feature) { |
| 204 | case C_HUB_LOCAL_POWER: | 200 | case C_HUB_LOCAL_POWER: |
| 205 | /* FIXME: maybe plug bit 0 to the power input status, | 201 | /* FIXME: maybe plug bit 0 to the power input status, |
| @@ -211,7 +207,6 @@ static int wusbhc_rh_clear_hub_feat(struct wusbhc *wusbhc, u16 feature) | |||
| 211 | default: | 207 | default: |
| 212 | result = -EPIPE; | 208 | result = -EPIPE; |
| 213 | } | 209 | } |
| 214 | d_fnend(4, dev, "(%p, feature 0x%04u), %d\n", wusbhc, feature, result); | ||
| 215 | return result; | 210 | return result; |
| 216 | } | 211 | } |
| 217 | 212 | ||
| @@ -238,14 +233,10 @@ static int wusbhc_rh_get_hub_status(struct wusbhc *wusbhc, u32 *buf, | |||
| 238 | static int wusbhc_rh_set_port_feat(struct wusbhc *wusbhc, u16 feature, | 233 | static int wusbhc_rh_set_port_feat(struct wusbhc *wusbhc, u16 feature, |
| 239 | u8 selector, u8 port_idx) | 234 | u8 selector, u8 port_idx) |
| 240 | { | 235 | { |
| 241 | int result = -EINVAL; | ||
| 242 | struct device *dev = wusbhc->dev; | 236 | struct device *dev = wusbhc->dev; |
| 243 | 237 | ||
| 244 | d_fnstart(4, dev, "(feat 0x%04u, selector 0x%u, port_idx %d)\n", | ||
| 245 | feature, selector, port_idx); | ||
| 246 | |||
| 247 | if (port_idx > wusbhc->ports_max) | 238 | if (port_idx > wusbhc->ports_max) |
| 248 | goto error; | 239 | return -EINVAL; |
| 249 | 240 | ||
| 250 | switch (feature) { | 241 | switch (feature) { |
| 251 | /* According to USB2.0[11.24.2.13]p2, these features | 242 | /* According to USB2.0[11.24.2.13]p2, these features |
| @@ -255,35 +246,27 @@ static int wusbhc_rh_set_port_feat(struct wusbhc *wusbhc, u16 feature, | |||
| 255 | case USB_PORT_FEAT_C_SUSPEND: | 246 | case USB_PORT_FEAT_C_SUSPEND: |
| 256 | case USB_PORT_FEAT_C_CONNECTION: | 247 | case USB_PORT_FEAT_C_CONNECTION: |
| 257 | case USB_PORT_FEAT_C_RESET: | 248 | case USB_PORT_FEAT_C_RESET: |
| 258 | result = 0; | 249 | return 0; |
| 259 | break; | ||
| 260 | |||
| 261 | case USB_PORT_FEAT_POWER: | 250 | case USB_PORT_FEAT_POWER: |
| 262 | /* No such thing, but we fake it works */ | 251 | /* No such thing, but we fake it works */ |
| 263 | mutex_lock(&wusbhc->mutex); | 252 | mutex_lock(&wusbhc->mutex); |
| 264 | wusb_port_by_idx(wusbhc, port_idx)->status |= USB_PORT_STAT_POWER; | 253 | wusb_port_by_idx(wusbhc, port_idx)->status |= USB_PORT_STAT_POWER; |
| 265 | mutex_unlock(&wusbhc->mutex); | 254 | mutex_unlock(&wusbhc->mutex); |
| 266 | result = 0; | 255 | return 0; |
| 267 | break; | ||
| 268 | case USB_PORT_FEAT_RESET: | 256 | case USB_PORT_FEAT_RESET: |
| 269 | result = wusbhc_rh_port_reset(wusbhc, port_idx); | 257 | return wusbhc_rh_port_reset(wusbhc, port_idx); |
| 270 | break; | ||
| 271 | case USB_PORT_FEAT_ENABLE: | 258 | case USB_PORT_FEAT_ENABLE: |
| 272 | case USB_PORT_FEAT_SUSPEND: | 259 | case USB_PORT_FEAT_SUSPEND: |
| 273 | dev_err(dev, "(port_idx %d) set feat %d/%d UNIMPLEMENTED\n", | 260 | dev_err(dev, "(port_idx %d) set feat %d/%d UNIMPLEMENTED\n", |
| 274 | port_idx, feature, selector); | 261 | port_idx, feature, selector); |
| 275 | result = -ENOSYS; | 262 | return -ENOSYS; |
| 276 | break; | ||
| 277 | default: | 263 | default: |
| 278 | dev_err(dev, "(port_idx %d) set feat %d/%d UNKNOWN\n", | 264 | dev_err(dev, "(port_idx %d) set feat %d/%d UNKNOWN\n", |
| 279 | port_idx, feature, selector); | 265 | port_idx, feature, selector); |
| 280 | result = -EPIPE; | 266 | return -EPIPE; |
| 281 | break; | ||
| 282 | } | 267 | } |
| 283 | error: | 268 | |
| 284 | d_fnend(4, dev, "(feat 0x%04u, selector 0x%u, port_idx %d) = %d\n", | 269 | return 0; |
| 285 | feature, selector, port_idx, result); | ||
| 286 | return result; | ||
| 287 | } | 270 | } |
| 288 | 271 | ||
| 289 | /* | 272 | /* |
| @@ -294,17 +277,13 @@ error: | |||
| 294 | static int wusbhc_rh_clear_port_feat(struct wusbhc *wusbhc, u16 feature, | 277 | static int wusbhc_rh_clear_port_feat(struct wusbhc *wusbhc, u16 feature, |
| 295 | u8 selector, u8 port_idx) | 278 | u8 selector, u8 port_idx) |
| 296 | { | 279 | { |
| 297 | int result = -EINVAL; | 280 | int result = 0; |
| 298 | struct device *dev = wusbhc->dev; | 281 | struct device *dev = wusbhc->dev; |
| 299 | 282 | ||
| 300 | d_fnstart(4, dev, "(wusbhc %p feat 0x%04x selector %d port_idx %d)\n", | ||
| 301 | wusbhc, feature, selector, port_idx); | ||
| 302 | |||
| 303 | if (port_idx > wusbhc->ports_max) | 283 | if (port_idx > wusbhc->ports_max) |
| 304 | goto error; | 284 | return -EINVAL; |
| 305 | 285 | ||
| 306 | mutex_lock(&wusbhc->mutex); | 286 | mutex_lock(&wusbhc->mutex); |
| 307 | result = 0; | ||
| 308 | switch (feature) { | 287 | switch (feature) { |
| 309 | case USB_PORT_FEAT_POWER: /* fake port always on */ | 288 | case USB_PORT_FEAT_POWER: /* fake port always on */ |
| 310 | /* According to USB2.0[11.24.2.7.1.4], no need to implement? */ | 289 | /* According to USB2.0[11.24.2.7.1.4], no need to implement? */ |
| @@ -324,10 +303,8 @@ static int wusbhc_rh_clear_port_feat(struct wusbhc *wusbhc, u16 feature, | |||
| 324 | break; | 303 | break; |
| 325 | case USB_PORT_FEAT_SUSPEND: | 304 | case USB_PORT_FEAT_SUSPEND: |
| 326 | case USB_PORT_FEAT_C_SUSPEND: | 305 | case USB_PORT_FEAT_C_SUSPEND: |
| 327 | case 0xffff: /* ??? FIXME */ | ||
| 328 | dev_err(dev, "(port_idx %d) Clear feat %d/%d UNIMPLEMENTED\n", | 306 | dev_err(dev, "(port_idx %d) Clear feat %d/%d UNIMPLEMENTED\n", |
| 329 | port_idx, feature, selector); | 307 | port_idx, feature, selector); |
| 330 | /* dump_stack(); */ | ||
| 331 | result = -ENOSYS; | 308 | result = -ENOSYS; |
| 332 | break; | 309 | break; |
| 333 | default: | 310 | default: |
| @@ -337,9 +314,7 @@ static int wusbhc_rh_clear_port_feat(struct wusbhc *wusbhc, u16 feature, | |||
| 337 | break; | 314 | break; |
| 338 | } | 315 | } |
| 339 | mutex_unlock(&wusbhc->mutex); | 316 | mutex_unlock(&wusbhc->mutex); |
| 340 | error: | 317 | |
| 341 | d_fnend(4, dev, "(wusbhc %p feat 0x%04x selector %d port_idx %d) = " | ||
| 342 | "%d\n", wusbhc, feature, selector, port_idx, result); | ||
| 343 | return result; | 318 | return result; |
| 344 | } | 319 | } |
| 345 | 320 | ||
| @@ -351,22 +326,17 @@ error: | |||
| 351 | static int wusbhc_rh_get_port_status(struct wusbhc *wusbhc, u16 port_idx, | 326 | static int wusbhc_rh_get_port_status(struct wusbhc *wusbhc, u16 port_idx, |
| 352 | u32 *_buf, u16 wLength) | 327 | u32 *_buf, u16 wLength) |
| 353 | { | 328 | { |
| 354 | int result = -EINVAL; | ||
| 355 | u16 *buf = (u16 *) _buf; | 329 | u16 *buf = (u16 *) _buf; |
| 356 | 330 | ||
| 357 | d_fnstart(1, wusbhc->dev, "(wusbhc %p port_idx %u wLength %u)\n", | ||
| 358 | wusbhc, port_idx, wLength); | ||
| 359 | if (port_idx > wusbhc->ports_max) | 331 | if (port_idx > wusbhc->ports_max) |
| 360 | goto error; | 332 | return -EINVAL; |
| 333 | |||
| 361 | mutex_lock(&wusbhc->mutex); | 334 | mutex_lock(&wusbhc->mutex); |
| 362 | buf[0] = cpu_to_le16(wusb_port_by_idx(wusbhc, port_idx)->status); | 335 | buf[0] = cpu_to_le16(wusb_port_by_idx(wusbhc, port_idx)->status); |
| 363 | buf[1] = cpu_to_le16(wusb_port_by_idx(wusbhc, port_idx)->change); | 336 | buf[1] = cpu_to_le16(wusb_port_by_idx(wusbhc, port_idx)->change); |
| 364 | result = 0; | ||
| 365 | mutex_unlock(&wusbhc->mutex); | 337 | mutex_unlock(&wusbhc->mutex); |
| 366 | error: | 338 | |
| 367 | d_fnend(1, wusbhc->dev, "(wusbhc %p) = %d, buffer:\n", wusbhc, result); | 339 | return 0; |
| 368 | d_dump(1, wusbhc->dev, _buf, wLength); | ||
| 369 | return result; | ||
| 370 | } | 340 | } |
| 371 | 341 | ||
| 372 | /* | 342 | /* |
diff --git a/drivers/usb/wusbcore/security.c b/drivers/usb/wusbcore/security.c index a101cad6a8d..f4aa28eca70 100644 --- a/drivers/usb/wusbcore/security.c +++ b/drivers/usb/wusbcore/security.c | |||
| @@ -27,19 +27,6 @@ | |||
| 27 | #include <linux/random.h> | 27 | #include <linux/random.h> |
| 28 | #include "wusbhc.h" | 28 | #include "wusbhc.h" |
| 29 | 29 | ||
| 30 | /* | ||
| 31 | * DEBUG & SECURITY WARNING!!!! | ||
| 32 | * | ||
| 33 | * If you enable this past 1, the debug code will weaken the | ||
| 34 | * cryptographic safety of the system (on purpose, for debugging). | ||
| 35 | * | ||
| 36 | * Weaken means: | ||
| 37 | * we print secret keys and intermediate values all the way, | ||
| 38 | */ | ||
| 39 | #undef D_LOCAL | ||
| 40 | #define D_LOCAL 2 | ||
| 41 | #include <linux/uwb/debug.h> | ||
| 42 | |||
| 43 | static void wusbhc_set_gtk_callback(struct urb *urb); | 30 | static void wusbhc_set_gtk_callback(struct urb *urb); |
| 44 | static void wusbhc_gtk_rekey_done_work(struct work_struct *work); | 31 | static void wusbhc_gtk_rekey_done_work(struct work_struct *work); |
| 45 | 32 | ||
| @@ -219,7 +206,6 @@ int wusb_dev_sec_add(struct wusbhc *wusbhc, | |||
| 219 | const void *itr, *top; | 206 | const void *itr, *top; |
| 220 | char buf[64]; | 207 | char buf[64]; |
| 221 | 208 | ||
| 222 | d_fnstart(3, dev, "(usb_dev %p, wusb_dev %p)\n", usb_dev, wusb_dev); | ||
| 223 | result = usb_get_descriptor(usb_dev, USB_DT_SECURITY, | 209 | result = usb_get_descriptor(usb_dev, USB_DT_SECURITY, |
| 224 | 0, &secd, sizeof(secd)); | 210 | 0, &secd, sizeof(secd)); |
| 225 | if (result < sizeof(secd)) { | 211 | if (result < sizeof(secd)) { |
| @@ -228,8 +214,6 @@ int wusb_dev_sec_add(struct wusbhc *wusbhc, | |||
| 228 | goto error_secd; | 214 | goto error_secd; |
| 229 | } | 215 | } |
| 230 | secd_size = le16_to_cpu(secd.wTotalLength); | 216 | secd_size = le16_to_cpu(secd.wTotalLength); |
| 231 | d_printf(5, dev, "got %d bytes of sec descriptor, total is %d\n", | ||
| 232 | result, secd_size); | ||
| 233 | secd_buf = kmalloc(secd_size, GFP_KERNEL); | 217 | secd_buf = kmalloc(secd_size, GFP_KERNEL); |
| 234 | if (secd_buf == NULL) { | 218 | if (secd_buf == NULL) { |
| 235 | dev_err(dev, "Can't allocate space for security descriptors\n"); | 219 | dev_err(dev, "Can't allocate space for security descriptors\n"); |
| @@ -242,7 +226,6 @@ int wusb_dev_sec_add(struct wusbhc *wusbhc, | |||
| 242 | "not enough data: %d\n", result); | 226 | "not enough data: %d\n", result); |
| 243 | goto error_secd_all; | 227 | goto error_secd_all; |
| 244 | } | 228 | } |
| 245 | d_printf(5, dev, "got %d bytes of sec descriptors\n", result); | ||
| 246 | bytes = 0; | 229 | bytes = 0; |
| 247 | itr = secd_buf + sizeof(secd); | 230 | itr = secd_buf + sizeof(secd); |
| 248 | top = secd_buf + result; | 231 | top = secd_buf + result; |
| @@ -279,14 +262,12 @@ int wusb_dev_sec_add(struct wusbhc *wusbhc, | |||
| 279 | goto error_no_ccm1; | 262 | goto error_no_ccm1; |
| 280 | } | 263 | } |
| 281 | wusb_dev->ccm1_etd = *ccm1_etd; | 264 | wusb_dev->ccm1_etd = *ccm1_etd; |
| 282 | dev_info(dev, "supported encryption: %s; using %s (0x%02x/%02x)\n", | 265 | dev_dbg(dev, "supported encryption: %s; using %s (0x%02x/%02x)\n", |
| 283 | buf, wusb_et_name(ccm1_etd->bEncryptionType), | 266 | buf, wusb_et_name(ccm1_etd->bEncryptionType), |
| 284 | ccm1_etd->bEncryptionValue, ccm1_etd->bAuthKeyIndex); | 267 | ccm1_etd->bEncryptionValue, ccm1_etd->bAuthKeyIndex); |
| 285 | result = 0; | 268 | result = 0; |
| 286 | kfree(secd_buf); | 269 | kfree(secd_buf); |
| 287 | out: | 270 | out: |
| 288 | d_fnend(3, dev, "(usb_dev %p, wusb_dev %p) = %d\n", | ||
| 289 | usb_dev, wusb_dev, result); | ||
| 290 | return result; | 271 | return result; |
| 291 | 272 | ||
| 292 | 273 | ||
| @@ -303,32 +284,6 @@ void wusb_dev_sec_rm(struct wusb_dev *wusb_dev) | |||
| 303 | /* Nothing so far */ | 284 | /* Nothing so far */ |
| 304 | } | 285 | } |
| 305 | 286 | ||
| 306 | static void hs_printk(unsigned level, struct device *dev, | ||
| 307 | struct usb_handshake *hs) | ||
| 308 | { | ||
| 309 | d_printf(level, dev, | ||
| 310 | " bMessageNumber: %u\n" | ||
| 311 | " bStatus: %u\n" | ||
| 312 | " tTKID: %02x %02x %02x\n" | ||
| 313 | " CDID: %02x %02x %02x %02x %02x %02x %02x %02x\n" | ||
| 314 | " %02x %02x %02x %02x %02x %02x %02x %02x\n" | ||
| 315 | " nonce: %02x %02x %02x %02x %02x %02x %02x %02x\n" | ||
| 316 | " %02x %02x %02x %02x %02x %02x %02x %02x\n" | ||
| 317 | " MIC: %02x %02x %02x %02x %02x %02x %02x %02x\n", | ||
| 318 | hs->bMessageNumber, hs->bStatus, | ||
| 319 | hs->tTKID[2], hs->tTKID[1], hs->tTKID[0], | ||
| 320 | hs->CDID[0], hs->CDID[1], hs->CDID[2], hs->CDID[3], | ||
| 321 | hs->CDID[4], hs->CDID[5], hs->CDID[6], hs->CDID[7], | ||
| 322 | hs->CDID[8], hs->CDID[9], hs->CDID[10], hs->CDID[11], | ||
| 323 | hs->CDID[12], hs->CDID[13], hs->CDID[14], hs->CDID[15], | ||
| 324 | hs->nonce[0], hs->nonce[1], hs->nonce[2], hs->nonce[3], | ||
| 325 | hs->nonce[4], hs->nonce[5], hs->nonce[6], hs->nonce[7], | ||
| 326 | hs->nonce[8], hs->nonce[9], hs->nonce[10], hs->nonce[11], | ||
| 327 | hs->nonce[12], hs->nonce[13], hs->nonce[14], hs->nonce[15], | ||
| 328 | hs->MIC[0], hs->MIC[1], hs->MIC[2], hs->MIC[3], | ||
| 329 | hs->MIC[4], hs->MIC[5], hs->MIC[6], hs->MIC[7]); | ||
| 330 | } | ||
| 331 | |||
| 332 | /** | 287 | /** |
| 333 | * Update the address of an unauthenticated WUSB device | 288 | * Update the address of an unauthenticated WUSB device |
| 334 | * | 289 | * |
| @@ -338,8 +293,7 @@ static void hs_printk(unsigned level, struct device *dev, | |||
| 338 | * Before the device's address (as known by it) was usb_dev->devnum | | 293 | * Before the device's address (as known by it) was usb_dev->devnum | |
| 339 | * 0x80 (unauthenticated address). With this we update it to usb_dev->devnum. | 294 | * 0x80 (unauthenticated address). With this we update it to usb_dev->devnum. |
| 340 | */ | 295 | */ |
| 341 | static int wusb_dev_update_address(struct wusbhc *wusbhc, | 296 | int wusb_dev_update_address(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev) |
| 342 | struct wusb_dev *wusb_dev) | ||
| 343 | { | 297 | { |
| 344 | int result = -ENOMEM; | 298 | int result = -ENOMEM; |
| 345 | struct usb_device *usb_dev = wusb_dev->usb_dev; | 299 | struct usb_device *usb_dev = wusb_dev->usb_dev; |
| @@ -422,9 +376,6 @@ int wusb_dev_4way_handshake(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev, | |||
| 422 | get_random_bytes(&hs[0].nonce, sizeof(hs[0].nonce)); | 376 | get_random_bytes(&hs[0].nonce, sizeof(hs[0].nonce)); |
| 423 | memset(hs[0].MIC, 0, sizeof(hs[0].MIC)); /* Per WUSB1.0[T7-22] */ | 377 | memset(hs[0].MIC, 0, sizeof(hs[0].MIC)); /* Per WUSB1.0[T7-22] */ |
| 424 | 378 | ||
| 425 | d_printf(1, dev, "I: sending hs1:\n"); | ||
| 426 | hs_printk(2, dev, &hs[0]); | ||
| 427 | |||
| 428 | result = usb_control_msg( | 379 | result = usb_control_msg( |
| 429 | usb_dev, usb_sndctrlpipe(usb_dev, 0), | 380 | usb_dev, usb_sndctrlpipe(usb_dev, 0), |
| 430 | USB_REQ_SET_HANDSHAKE, | 381 | USB_REQ_SET_HANDSHAKE, |
| @@ -445,8 +396,6 @@ int wusb_dev_4way_handshake(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev, | |||
| 445 | dev_err(dev, "Handshake2: request failed: %d\n", result); | 396 | dev_err(dev, "Handshake2: request failed: %d\n", result); |
| 446 | goto error_hs2; | 397 | goto error_hs2; |
| 447 | } | 398 | } |
| 448 | d_printf(1, dev, "got HS2:\n"); | ||
| 449 | hs_printk(2, dev, &hs[1]); | ||
| 450 | 399 | ||
| 451 | result = -EINVAL; | 400 | result = -EINVAL; |
| 452 | if (hs[1].bMessageNumber != 2) { | 401 | if (hs[1].bMessageNumber != 2) { |
| @@ -487,10 +436,6 @@ int wusb_dev_4way_handshake(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev, | |||
| 487 | result); | 436 | result); |
| 488 | goto error_hs2; | 437 | goto error_hs2; |
| 489 | } | 438 | } |
| 490 | d_printf(2, dev, "KCK:\n"); | ||
| 491 | d_dump(2, dev, keydvt_out.kck, sizeof(keydvt_out.kck)); | ||
| 492 | d_printf(2, dev, "PTK:\n"); | ||
| 493 | d_dump(2, dev, keydvt_out.ptk, sizeof(keydvt_out.ptk)); | ||
| 494 | 439 | ||
| 495 | /* Compute MIC and verify it */ | 440 | /* Compute MIC and verify it */ |
| 496 | result = wusb_oob_mic(mic, keydvt_out.kck, &ccm_n, &hs[1]); | 441 | result = wusb_oob_mic(mic, keydvt_out.kck, &ccm_n, &hs[1]); |
| @@ -500,8 +445,6 @@ int wusb_dev_4way_handshake(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev, | |||
| 500 | goto error_hs2; | 445 | goto error_hs2; |
| 501 | } | 446 | } |
| 502 | 447 | ||
| 503 | d_printf(2, dev, "MIC:\n"); | ||
| 504 | d_dump(2, dev, mic, sizeof(mic)); | ||
| 505 | if (memcmp(hs[1].MIC, mic, sizeof(hs[1].MIC))) { | 448 | if (memcmp(hs[1].MIC, mic, sizeof(hs[1].MIC))) { |
| 506 | dev_err(dev, "Handshake2 failed: MIC mismatch\n"); | 449 | dev_err(dev, "Handshake2 failed: MIC mismatch\n"); |
| 507 | goto error_hs2; | 450 | goto error_hs2; |
| @@ -521,9 +464,6 @@ int wusb_dev_4way_handshake(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev, | |||
| 521 | goto error_hs2; | 464 | goto error_hs2; |
| 522 | } | 465 | } |
| 523 | 466 | ||
| 524 | d_printf(1, dev, "I: sending hs3:\n"); | ||
| 525 | hs_printk(2, dev, &hs[2]); | ||
| 526 | |||
| 527 | result = usb_control_msg( | 467 | result = usb_control_msg( |
| 528 | usb_dev, usb_sndctrlpipe(usb_dev, 0), | 468 | usb_dev, usb_sndctrlpipe(usb_dev, 0), |
| 529 | USB_REQ_SET_HANDSHAKE, | 469 | USB_REQ_SET_HANDSHAKE, |
| @@ -534,14 +474,11 @@ int wusb_dev_4way_handshake(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev, | |||
| 534 | goto error_hs3; | 474 | goto error_hs3; |
| 535 | } | 475 | } |
| 536 | 476 | ||
| 537 | d_printf(1, dev, "I: turning on encryption on host for device\n"); | ||
| 538 | d_dump(2, dev, keydvt_out.ptk, sizeof(keydvt_out.ptk)); | ||
| 539 | result = wusbhc->set_ptk(wusbhc, wusb_dev->port_idx, tkid, | 477 | result = wusbhc->set_ptk(wusbhc, wusb_dev->port_idx, tkid, |
| 540 | keydvt_out.ptk, sizeof(keydvt_out.ptk)); | 478 | keydvt_out.ptk, sizeof(keydvt_out.ptk)); |
| 541 | if (result < 0) | 479 | if (result < 0) |
| 542 | goto error_wusbhc_set_ptk; | 480 | goto error_wusbhc_set_ptk; |
| 543 | 481 | ||
| 544 | d_printf(1, dev, "I: setting a GTK\n"); | ||
| 545 | result = wusb_dev_set_gtk(wusbhc, wusb_dev); | 482 | result = wusb_dev_set_gtk(wusbhc, wusb_dev); |
| 546 | if (result < 0) { | 483 | if (result < 0) { |
| 547 | dev_err(dev, "Set GTK for device: request failed: %d\n", | 484 | dev_err(dev, "Set GTK for device: request failed: %d\n", |
| @@ -551,13 +488,12 @@ int wusb_dev_4way_handshake(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev, | |||
| 551 | 488 | ||
| 552 | /* Update the device's address from unauth to auth */ | 489 | /* Update the device's address from unauth to auth */ |
| 553 | if (usb_dev->authenticated == 0) { | 490 | if (usb_dev->authenticated == 0) { |
| 554 | d_printf(1, dev, "I: updating addres to auth from non-auth\n"); | ||
| 555 | result = wusb_dev_update_address(wusbhc, wusb_dev); | 491 | result = wusb_dev_update_address(wusbhc, wusb_dev); |
| 556 | if (result < 0) | 492 | if (result < 0) |
| 557 | goto error_dev_update_address; | 493 | goto error_dev_update_address; |
| 558 | } | 494 | } |
| 559 | result = 0; | 495 | result = 0; |
| 560 | d_printf(1, dev, "I: 4way handshke done, device authenticated\n"); | 496 | dev_info(dev, "device authenticated\n"); |
| 561 | 497 | ||
| 562 | error_dev_update_address: | 498 | error_dev_update_address: |
| 563 | error_wusbhc_set_gtk: | 499 | error_wusbhc_set_gtk: |
| @@ -570,10 +506,8 @@ error_hs1: | |||
| 570 | memset(&keydvt_in, 0, sizeof(keydvt_in)); | 506 | memset(&keydvt_in, 0, sizeof(keydvt_in)); |
| 571 | memset(&ccm_n, 0, sizeof(ccm_n)); | 507 | memset(&ccm_n, 0, sizeof(ccm_n)); |
| 572 | memset(mic, 0, sizeof(mic)); | 508 | memset(mic, 0, sizeof(mic)); |
| 573 | if (result < 0) { | 509 | if (result < 0) |
| 574 | /* error path */ | ||
| 575 | wusb_dev_set_encryption(usb_dev, 0); | 510 | wusb_dev_set_encryption(usb_dev, 0); |
| 576 | } | ||
| 577 | error_dev_set_encryption: | 511 | error_dev_set_encryption: |
| 578 | kfree(hs); | 512 | kfree(hs); |
| 579 | error_kzalloc: | 513 | error_kzalloc: |
diff --git a/drivers/usb/wusbcore/wa-nep.c b/drivers/usb/wusbcore/wa-nep.c index 3f542990c73..17d2626038b 100644 --- a/drivers/usb/wusbcore/wa-nep.c +++ b/drivers/usb/wusbcore/wa-nep.c | |||
| @@ -51,7 +51,7 @@ | |||
| 51 | */ | 51 | */ |
| 52 | #include <linux/workqueue.h> | 52 | #include <linux/workqueue.h> |
| 53 | #include <linux/ctype.h> | 53 | #include <linux/ctype.h> |
| 54 | #include <linux/uwb/debug.h> | 54 | |
| 55 | #include "wa-hc.h" | 55 | #include "wa-hc.h" |
| 56 | #include "wusbhc.h" | 56 | #include "wusbhc.h" |
| 57 | 57 | ||
| @@ -139,13 +139,10 @@ static void wa_notif_dispatch(struct work_struct *ws) | |||
| 139 | /* FIXME: unimplemented WA NOTIFs */ | 139 | /* FIXME: unimplemented WA NOTIFs */ |
| 140 | /* fallthru */ | 140 | /* fallthru */ |
| 141 | default: | 141 | default: |
| 142 | if (printk_ratelimit()) { | 142 | dev_err(dev, "HWA: unknown notification 0x%x, " |
| 143 | dev_err(dev, "HWA: unknown notification 0x%x, " | 143 | "%zu bytes; discarding\n", |
| 144 | "%zu bytes; discarding\n", | 144 | notif_hdr->bNotifyType, |
| 145 | notif_hdr->bNotifyType, | 145 | (size_t)notif_hdr->bLength); |
| 146 | (size_t)notif_hdr->bLength); | ||
| 147 | dump_bytes(dev, notif_hdr, 16); | ||
| 148 | } | ||
| 149 | break; | 146 | break; |
| 150 | } | 147 | } |
| 151 | } | 148 | } |
| @@ -160,12 +157,9 @@ out: | |||
| 160 | * discard the data, as this should not happen. | 157 | * discard the data, as this should not happen. |
| 161 | */ | 158 | */ |
| 162 | exhausted_buffer: | 159 | exhausted_buffer: |
| 163 | if (!printk_ratelimit()) | ||
| 164 | goto out; | ||
| 165 | dev_warn(dev, "HWA: device sent short notification, " | 160 | dev_warn(dev, "HWA: device sent short notification, " |
| 166 | "%d bytes missing; discarding %d bytes.\n", | 161 | "%d bytes missing; discarding %d bytes.\n", |
| 167 | missing, (int)size); | 162 | missing, (int)size); |
| 168 | dump_bytes(dev, itr, size); | ||
| 169 | goto out; | 163 | goto out; |
| 170 | } | 164 | } |
| 171 | 165 | ||
diff --git a/drivers/usb/wusbcore/wa-rpipe.c b/drivers/usb/wusbcore/wa-rpipe.c index f18e4aae66e..7369655f69c 100644 --- a/drivers/usb/wusbcore/wa-rpipe.c +++ b/drivers/usb/wusbcore/wa-rpipe.c | |||
| @@ -60,13 +60,10 @@ | |||
| 60 | #include <linux/init.h> | 60 | #include <linux/init.h> |
| 61 | #include <asm/atomic.h> | 61 | #include <asm/atomic.h> |
| 62 | #include <linux/bitmap.h> | 62 | #include <linux/bitmap.h> |
| 63 | |||
| 63 | #include "wusbhc.h" | 64 | #include "wusbhc.h" |
| 64 | #include "wa-hc.h" | 65 | #include "wa-hc.h" |
| 65 | 66 | ||
| 66 | #define D_LOCAL 0 | ||
| 67 | #include <linux/uwb/debug.h> | ||
| 68 | |||
| 69 | |||
| 70 | static int __rpipe_get_descr(struct wahc *wa, | 67 | static int __rpipe_get_descr(struct wahc *wa, |
| 71 | struct usb_rpipe_descriptor *descr, u16 index) | 68 | struct usb_rpipe_descriptor *descr, u16 index) |
| 72 | { | 69 | { |
| @@ -76,7 +73,6 @@ static int __rpipe_get_descr(struct wahc *wa, | |||
| 76 | /* Get the RPIPE descriptor -- we cannot use the usb_get_descriptor() | 73 | /* Get the RPIPE descriptor -- we cannot use the usb_get_descriptor() |
| 77 | * function because the arguments are different. | 74 | * function because the arguments are different. |
| 78 | */ | 75 | */ |
| 79 | d_printf(1, dev, "rpipe %u: get descr\n", index); | ||
| 80 | result = usb_control_msg( | 76 | result = usb_control_msg( |
| 81 | wa->usb_dev, usb_rcvctrlpipe(wa->usb_dev, 0), | 77 | wa->usb_dev, usb_rcvctrlpipe(wa->usb_dev, 0), |
| 82 | USB_REQ_GET_DESCRIPTOR, | 78 | USB_REQ_GET_DESCRIPTOR, |
| @@ -115,7 +111,6 @@ static int __rpipe_set_descr(struct wahc *wa, | |||
| 115 | /* we cannot use the usb_get_descriptor() function because the | 111 | /* we cannot use the usb_get_descriptor() function because the |
| 116 | * arguments are different. | 112 | * arguments are different. |
| 117 | */ | 113 | */ |
| 118 | d_printf(1, dev, "rpipe %u: set descr\n", index); | ||
| 119 | result = usb_control_msg( | 114 | result = usb_control_msg( |
| 120 | wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0), | 115 | wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0), |
| 121 | USB_REQ_SET_DESCRIPTOR, | 116 | USB_REQ_SET_DESCRIPTOR, |
| @@ -174,13 +169,12 @@ void rpipe_destroy(struct kref *_rpipe) | |||
| 174 | { | 169 | { |
| 175 | struct wa_rpipe *rpipe = container_of(_rpipe, struct wa_rpipe, refcnt); | 170 | struct wa_rpipe *rpipe = container_of(_rpipe, struct wa_rpipe, refcnt); |
| 176 | u8 index = le16_to_cpu(rpipe->descr.wRPipeIndex); | 171 | u8 index = le16_to_cpu(rpipe->descr.wRPipeIndex); |
| 177 | d_fnstart(1, NULL, "(rpipe %p %u)\n", rpipe, index); | 172 | |
| 178 | if (rpipe->ep) | 173 | if (rpipe->ep) |
| 179 | rpipe->ep->hcpriv = NULL; | 174 | rpipe->ep->hcpriv = NULL; |
| 180 | rpipe_put_idx(rpipe->wa, index); | 175 | rpipe_put_idx(rpipe->wa, index); |
| 181 | wa_put(rpipe->wa); | 176 | wa_put(rpipe->wa); |
| 182 | kfree(rpipe); | 177 | kfree(rpipe); |
| 183 | d_fnend(1, NULL, "(rpipe %p %u)\n", rpipe, index); | ||
| 184 | } | 178 | } |
| 185 | EXPORT_SYMBOL_GPL(rpipe_destroy); | 179 | EXPORT_SYMBOL_GPL(rpipe_destroy); |
| 186 | 180 | ||
| @@ -202,7 +196,6 @@ static int rpipe_get_idle(struct wa_rpipe **prpipe, struct wahc *wa, u8 crs, | |||
| 202 | struct wa_rpipe *rpipe; | 196 | struct wa_rpipe *rpipe; |
| 203 | struct device *dev = &wa->usb_iface->dev; | 197 | struct device *dev = &wa->usb_iface->dev; |
| 204 | 198 | ||
| 205 | d_fnstart(3, dev, "(wa %p crs 0x%02x)\n", wa, crs); | ||
| 206 | rpipe = kzalloc(sizeof(*rpipe), gfp); | 199 | rpipe = kzalloc(sizeof(*rpipe), gfp); |
| 207 | if (rpipe == NULL) | 200 | if (rpipe == NULL) |
| 208 | return -ENOMEM; | 201 | return -ENOMEM; |
| @@ -223,14 +216,12 @@ static int rpipe_get_idle(struct wa_rpipe **prpipe, struct wahc *wa, u8 crs, | |||
| 223 | } | 216 | } |
| 224 | *prpipe = NULL; | 217 | *prpipe = NULL; |
| 225 | kfree(rpipe); | 218 | kfree(rpipe); |
| 226 | d_fnend(3, dev, "(wa %p crs 0x%02x) = -ENXIO\n", wa, crs); | ||
| 227 | return -ENXIO; | 219 | return -ENXIO; |
| 228 | 220 | ||
| 229 | found: | 221 | found: |
| 230 | set_bit(rpipe_idx, wa->rpipe_bm); | 222 | set_bit(rpipe_idx, wa->rpipe_bm); |
| 231 | rpipe->wa = wa_get(wa); | 223 | rpipe->wa = wa_get(wa); |
| 232 | *prpipe = rpipe; | 224 | *prpipe = rpipe; |
| 233 | d_fnstart(3, dev, "(wa %p crs 0x%02x) = 0\n", wa, crs); | ||
| 234 | return 0; | 225 | return 0; |
| 235 | } | 226 | } |
| 236 | 227 | ||
| @@ -239,7 +230,6 @@ static int __rpipe_reset(struct wahc *wa, unsigned index) | |||
| 239 | int result; | 230 | int result; |
| 240 | struct device *dev = &wa->usb_iface->dev; | 231 | struct device *dev = &wa->usb_iface->dev; |
| 241 | 232 | ||
| 242 | d_printf(1, dev, "rpipe %u: reset\n", index); | ||
| 243 | result = usb_control_msg( | 233 | result = usb_control_msg( |
| 244 | wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0), | 234 | wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0), |
| 245 | USB_REQ_RPIPE_RESET, | 235 | USB_REQ_RPIPE_RESET, |
| @@ -276,7 +266,6 @@ static struct usb_wireless_ep_comp_descriptor *rpipe_epc_find( | |||
| 276 | struct usb_descriptor_header *hdr; | 266 | struct usb_descriptor_header *hdr; |
| 277 | struct usb_wireless_ep_comp_descriptor *epcd; | 267 | struct usb_wireless_ep_comp_descriptor *epcd; |
| 278 | 268 | ||
| 279 | d_fnstart(3, dev, "(ep %p)\n", ep); | ||
| 280 | if (ep->desc.bEndpointAddress == 0) { | 269 | if (ep->desc.bEndpointAddress == 0) { |
| 281 | epcd = &epc0; | 270 | epcd = &epc0; |
| 282 | goto out; | 271 | goto out; |
| @@ -310,7 +299,6 @@ static struct usb_wireless_ep_comp_descriptor *rpipe_epc_find( | |||
| 310 | itr_size -= hdr->bDescriptorType; | 299 | itr_size -= hdr->bDescriptorType; |
| 311 | } | 300 | } |
| 312 | out: | 301 | out: |
| 313 | d_fnend(3, dev, "(ep %p) = %p\n", ep, epcd); | ||
| 314 | return epcd; | 302 | return epcd; |
| 315 | } | 303 | } |
| 316 | 304 | ||
| @@ -329,8 +317,6 @@ static int rpipe_aim(struct wa_rpipe *rpipe, struct wahc *wa, | |||
| 329 | struct usb_wireless_ep_comp_descriptor *epcd; | 317 | struct usb_wireless_ep_comp_descriptor *epcd; |
| 330 | u8 unauth; | 318 | u8 unauth; |
| 331 | 319 | ||
| 332 | d_fnstart(3, dev, "(rpipe %p wa %p ep %p, urb %p)\n", | ||
| 333 | rpipe, wa, ep, urb); | ||
| 334 | epcd = rpipe_epc_find(dev, ep); | 320 | epcd = rpipe_epc_find(dev, ep); |
| 335 | if (epcd == NULL) { | 321 | if (epcd == NULL) { |
| 336 | dev_err(dev, "ep 0x%02x: can't find companion descriptor\n", | 322 | dev_err(dev, "ep 0x%02x: can't find companion descriptor\n", |
| @@ -350,10 +336,12 @@ static int rpipe_aim(struct wa_rpipe *rpipe, struct wahc *wa, | |||
| 350 | /* FIXME: use maximum speed as supported or recommended by device */ | 336 | /* FIXME: use maximum speed as supported or recommended by device */ |
| 351 | rpipe->descr.bSpeed = usb_pipeendpoint(urb->pipe) == 0 ? | 337 | rpipe->descr.bSpeed = usb_pipeendpoint(urb->pipe) == 0 ? |
| 352 | UWB_PHY_RATE_53 : UWB_PHY_RATE_200; | 338 | UWB_PHY_RATE_53 : UWB_PHY_RATE_200; |
| 353 | d_printf(2, dev, "addr %u (0x%02x) rpipe #%u ep# %u speed %d\n", | 339 | |
| 354 | urb->dev->devnum, urb->dev->devnum | unauth, | 340 | dev_dbg(dev, "addr %u (0x%02x) rpipe #%u ep# %u speed %d\n", |
| 355 | le16_to_cpu(rpipe->descr.wRPipeIndex), | 341 | urb->dev->devnum, urb->dev->devnum | unauth, |
| 356 | usb_pipeendpoint(urb->pipe), rpipe->descr.bSpeed); | 342 | le16_to_cpu(rpipe->descr.wRPipeIndex), |
| 343 | usb_pipeendpoint(urb->pipe), rpipe->descr.bSpeed); | ||
| 344 | |||
| 357 | /* see security.c:wusb_update_address() */ | 345 | /* see security.c:wusb_update_address() */ |
| 358 | if (unlikely(urb->dev->devnum == 0x80)) | 346 | if (unlikely(urb->dev->devnum == 0x80)) |
| 359 | rpipe->descr.bDeviceAddress = 0; | 347 | rpipe->descr.bDeviceAddress = 0; |
| @@ -384,8 +372,6 @@ static int rpipe_aim(struct wa_rpipe *rpipe, struct wahc *wa, | |||
| 384 | } | 372 | } |
| 385 | result = 0; | 373 | result = 0; |
| 386 | error: | 374 | error: |
| 387 | d_fnend(3, dev, "(rpipe %p wa %p ep %p urb %p) = %d\n", | ||
| 388 | rpipe, wa, ep, urb, result); | ||
| 389 | return result; | 375 | return result; |
| 390 | } | 376 | } |
| 391 | 377 | ||
| @@ -405,8 +391,6 @@ static int rpipe_check_aim(const struct wa_rpipe *rpipe, const struct wahc *wa, | |||
| 405 | u8 unauth = (usb_dev->wusb && !usb_dev->authenticated) ? 0x80 : 0; | 391 | u8 unauth = (usb_dev->wusb && !usb_dev->authenticated) ? 0x80 : 0; |
| 406 | u8 portnum = wusb_port_no_to_idx(urb->dev->portnum); | 392 | u8 portnum = wusb_port_no_to_idx(urb->dev->portnum); |
| 407 | 393 | ||
| 408 | d_fnstart(3, dev, "(rpipe %p wa %p ep %p, urb %p)\n", | ||
| 409 | rpipe, wa, ep, urb); | ||
| 410 | #define AIM_CHECK(rdf, val, text) \ | 394 | #define AIM_CHECK(rdf, val, text) \ |
| 411 | do { \ | 395 | do { \ |
| 412 | if (rpipe->descr.rdf != (val)) { \ | 396 | if (rpipe->descr.rdf != (val)) { \ |
| @@ -451,8 +435,6 @@ int rpipe_get_by_ep(struct wahc *wa, struct usb_host_endpoint *ep, | |||
| 451 | struct wa_rpipe *rpipe; | 435 | struct wa_rpipe *rpipe; |
| 452 | u8 eptype; | 436 | u8 eptype; |
| 453 | 437 | ||
| 454 | d_fnstart(3, dev, "(wa %p ep %p urb %p gfp 0x%08x)\n", wa, ep, urb, | ||
| 455 | gfp); | ||
| 456 | mutex_lock(&wa->rpipe_mutex); | 438 | mutex_lock(&wa->rpipe_mutex); |
| 457 | rpipe = ep->hcpriv; | 439 | rpipe = ep->hcpriv; |
| 458 | if (rpipe != NULL) { | 440 | if (rpipe != NULL) { |
| @@ -462,9 +444,9 @@ int rpipe_get_by_ep(struct wahc *wa, struct usb_host_endpoint *ep, | |||
| 462 | goto error; | 444 | goto error; |
| 463 | } | 445 | } |
| 464 | __rpipe_get(rpipe); | 446 | __rpipe_get(rpipe); |
| 465 | d_printf(2, dev, "ep 0x%02x: reusing rpipe %u\n", | 447 | dev_dbg(dev, "ep 0x%02x: reusing rpipe %u\n", |
| 466 | ep->desc.bEndpointAddress, | 448 | ep->desc.bEndpointAddress, |
| 467 | le16_to_cpu(rpipe->descr.wRPipeIndex)); | 449 | le16_to_cpu(rpipe->descr.wRPipeIndex)); |
| 468 | } else { | 450 | } else { |
| 469 | /* hmm, assign idle rpipe, aim it */ | 451 | /* hmm, assign idle rpipe, aim it */ |
| 470 | result = -ENOBUFS; | 452 | result = -ENOBUFS; |
| @@ -480,14 +462,12 @@ int rpipe_get_by_ep(struct wahc *wa, struct usb_host_endpoint *ep, | |||
| 480 | ep->hcpriv = rpipe; | 462 | ep->hcpriv = rpipe; |
| 481 | rpipe->ep = ep; | 463 | rpipe->ep = ep; |
| 482 | __rpipe_get(rpipe); /* for caching into ep->hcpriv */ | 464 | __rpipe_get(rpipe); /* for caching into ep->hcpriv */ |
| 483 | d_printf(2, dev, "ep 0x%02x: using rpipe %u\n", | 465 | dev_dbg(dev, "ep 0x%02x: using rpipe %u\n", |
| 484 | ep->desc.bEndpointAddress, | 466 | ep->desc.bEndpointAddress, |
| 485 | le16_to_cpu(rpipe->descr.wRPipeIndex)); | 467 | le16_to_cpu(rpipe->descr.wRPipeIndex)); |
| 486 | } | 468 | } |
| 487 | d_dump(4, dev, &rpipe->descr, sizeof(rpipe->descr)); | ||
| 488 | error: | 469 | error: |
| 489 | mutex_unlock(&wa->rpipe_mutex); | 470 | mutex_unlock(&wa->rpipe_mutex); |
| 490 | d_fnend(3, dev, "(wa %p ep %p urb %p gfp 0x%08x)\n", wa, ep, urb, gfp); | ||
| 491 | return result; | 471 | return result; |
| 492 | } | 472 | } |
| 493 | 473 | ||
| @@ -507,7 +487,7 @@ int wa_rpipes_create(struct wahc *wa) | |||
| 507 | void wa_rpipes_destroy(struct wahc *wa) | 487 | void wa_rpipes_destroy(struct wahc *wa) |
| 508 | { | 488 | { |
| 509 | struct device *dev = &wa->usb_iface->dev; | 489 | struct device *dev = &wa->usb_iface->dev; |
| 510 | d_fnstart(3, dev, "(wa %p)\n", wa); | 490 | |
| 511 | if (!bitmap_empty(wa->rpipe_bm, wa->rpipes)) { | 491 | if (!bitmap_empty(wa->rpipe_bm, wa->rpipes)) { |
| 512 | char buf[256]; | 492 | char buf[256]; |
| 513 | WARN_ON(1); | 493 | WARN_ON(1); |
| @@ -515,7 +495,6 @@ void wa_rpipes_destroy(struct wahc *wa) | |||
| 515 | dev_err(dev, "BUG: pipes not released on exit: %s\n", buf); | 495 | dev_err(dev, "BUG: pipes not released on exit: %s\n", buf); |
| 516 | } | 496 | } |
| 517 | kfree(wa->rpipe_bm); | 497 | kfree(wa->rpipe_bm); |
| 518 | d_fnend(3, dev, "(wa %p)\n", wa); | ||
| 519 | } | 498 | } |
| 520 | 499 | ||
| 521 | /* | 500 | /* |
| @@ -530,33 +509,20 @@ void wa_rpipes_destroy(struct wahc *wa) | |||
| 530 | */ | 509 | */ |
| 531 | void rpipe_ep_disable(struct wahc *wa, struct usb_host_endpoint *ep) | 510 | void rpipe_ep_disable(struct wahc *wa, struct usb_host_endpoint *ep) |
| 532 | { | 511 | { |
| 533 | struct device *dev = &wa->usb_iface->dev; | ||
| 534 | struct wa_rpipe *rpipe; | 512 | struct wa_rpipe *rpipe; |
| 535 | d_fnstart(2, dev, "(wa %p ep %p)\n", wa, ep); | 513 | |
| 536 | mutex_lock(&wa->rpipe_mutex); | 514 | mutex_lock(&wa->rpipe_mutex); |
| 537 | rpipe = ep->hcpriv; | 515 | rpipe = ep->hcpriv; |
| 538 | if (rpipe != NULL) { | 516 | if (rpipe != NULL) { |
| 539 | unsigned rc = atomic_read(&rpipe->refcnt.refcount); | ||
| 540 | int result; | ||
| 541 | u16 index = le16_to_cpu(rpipe->descr.wRPipeIndex); | 517 | u16 index = le16_to_cpu(rpipe->descr.wRPipeIndex); |
| 542 | 518 | ||
| 543 | if (rc != 1) | 519 | usb_control_msg( |
| 544 | d_printf(1, dev, "(wa %p ep %p) rpipe %p refcnt %u\n", | ||
| 545 | wa, ep, rpipe, rc); | ||
| 546 | |||
| 547 | d_printf(1, dev, "rpipe %u: abort\n", index); | ||
| 548 | result = usb_control_msg( | ||
| 549 | wa->usb_dev, usb_rcvctrlpipe(wa->usb_dev, 0), | 520 | wa->usb_dev, usb_rcvctrlpipe(wa->usb_dev, 0), |
| 550 | USB_REQ_RPIPE_ABORT, | 521 | USB_REQ_RPIPE_ABORT, |
| 551 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_RPIPE, | 522 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_RPIPE, |
| 552 | 0, index, NULL, 0, 1000 /* FIXME: arbitrary */); | 523 | 0, index, NULL, 0, 1000 /* FIXME: arbitrary */); |
| 553 | if (result < 0 && result != -ENODEV /* dev is gone */) | ||
| 554 | d_printf(1, dev, "(wa %p rpipe %u): abort failed: %d\n", | ||
| 555 | wa, index, result); | ||
| 556 | rpipe_put(rpipe); | 524 | rpipe_put(rpipe); |
| 557 | } | 525 | } |
| 558 | mutex_unlock(&wa->rpipe_mutex); | 526 | mutex_unlock(&wa->rpipe_mutex); |
| 559 | d_fnend(2, dev, "(wa %p ep %p)\n", wa, ep); | ||
| 560 | return; | ||
| 561 | } | 527 | } |
| 562 | EXPORT_SYMBOL_GPL(rpipe_ep_disable); | 528 | EXPORT_SYMBOL_GPL(rpipe_ep_disable); |
diff --git a/drivers/usb/wusbcore/wa-xfer.c b/drivers/usb/wusbcore/wa-xfer.c index c038635d1c6..238a96aee3a 100644 --- a/drivers/usb/wusbcore/wa-xfer.c +++ b/drivers/usb/wusbcore/wa-xfer.c | |||
| @@ -82,13 +82,10 @@ | |||
| 82 | #include <linux/init.h> | 82 | #include <linux/init.h> |
| 83 | #include <linux/spinlock.h> | 83 | #include <linux/spinlock.h> |
| 84 | #include <linux/hash.h> | 84 | #include <linux/hash.h> |
| 85 | |||
| 85 | #include "wa-hc.h" | 86 | #include "wa-hc.h" |
| 86 | #include "wusbhc.h" | 87 | #include "wusbhc.h" |
| 87 | 88 | ||
| 88 | #undef D_LOCAL | ||
| 89 | #define D_LOCAL 0 /* 0 disabled, > 0 different levels... */ | ||
| 90 | #include <linux/uwb/debug.h> | ||
| 91 | |||
| 92 | enum { | 89 | enum { |
| 93 | WA_SEGS_MAX = 255, | 90 | WA_SEGS_MAX = 255, |
| 94 | }; | 91 | }; |
| @@ -180,7 +177,6 @@ static void wa_xfer_destroy(struct kref *_xfer) | |||
| 180 | } | 177 | } |
| 181 | } | 178 | } |
| 182 | kfree(xfer); | 179 | kfree(xfer); |
| 183 | d_printf(2, NULL, "xfer %p destroyed\n", xfer); | ||
| 184 | } | 180 | } |
| 185 | 181 | ||
| 186 | static void wa_xfer_get(struct wa_xfer *xfer) | 182 | static void wa_xfer_get(struct wa_xfer *xfer) |
| @@ -190,10 +186,7 @@ static void wa_xfer_get(struct wa_xfer *xfer) | |||
| 190 | 186 | ||
| 191 | static void wa_xfer_put(struct wa_xfer *xfer) | 187 | static void wa_xfer_put(struct wa_xfer *xfer) |
| 192 | { | 188 | { |
| 193 | d_fnstart(3, NULL, "(xfer %p) -- ref count bef put %d\n", | ||
| 194 | xfer, atomic_read(&xfer->refcnt.refcount)); | ||
| 195 | kref_put(&xfer->refcnt, wa_xfer_destroy); | 189 | kref_put(&xfer->refcnt, wa_xfer_destroy); |
| 196 | d_fnend(3, NULL, "(xfer %p) = void\n", xfer); | ||
| 197 | } | 190 | } |
| 198 | 191 | ||
| 199 | /* | 192 | /* |
| @@ -209,7 +202,7 @@ static void wa_xfer_put(struct wa_xfer *xfer) | |||
| 209 | static void wa_xfer_giveback(struct wa_xfer *xfer) | 202 | static void wa_xfer_giveback(struct wa_xfer *xfer) |
| 210 | { | 203 | { |
| 211 | unsigned long flags; | 204 | unsigned long flags; |
| 212 | d_fnstart(3, NULL, "(xfer %p)\n", xfer); | 205 | |
| 213 | spin_lock_irqsave(&xfer->wa->xfer_list_lock, flags); | 206 | spin_lock_irqsave(&xfer->wa->xfer_list_lock, flags); |
| 214 | list_del_init(&xfer->list_node); | 207 | list_del_init(&xfer->list_node); |
| 215 | spin_unlock_irqrestore(&xfer->wa->xfer_list_lock, flags); | 208 | spin_unlock_irqrestore(&xfer->wa->xfer_list_lock, flags); |
| @@ -217,7 +210,6 @@ static void wa_xfer_giveback(struct wa_xfer *xfer) | |||
| 217 | wusbhc_giveback_urb(xfer->wa->wusb, xfer->urb, xfer->result); | 210 | wusbhc_giveback_urb(xfer->wa->wusb, xfer->urb, xfer->result); |
| 218 | wa_put(xfer->wa); | 211 | wa_put(xfer->wa); |
| 219 | wa_xfer_put(xfer); | 212 | wa_xfer_put(xfer); |
| 220 | d_fnend(3, NULL, "(xfer %p) = void\n", xfer); | ||
| 221 | } | 213 | } |
| 222 | 214 | ||
| 223 | /* | 215 | /* |
| @@ -227,13 +219,10 @@ static void wa_xfer_giveback(struct wa_xfer *xfer) | |||
| 227 | */ | 219 | */ |
| 228 | static void wa_xfer_completion(struct wa_xfer *xfer) | 220 | static void wa_xfer_completion(struct wa_xfer *xfer) |
| 229 | { | 221 | { |
| 230 | d_fnstart(3, NULL, "(xfer %p)\n", xfer); | ||
| 231 | if (xfer->wusb_dev) | 222 | if (xfer->wusb_dev) |
| 232 | wusb_dev_put(xfer->wusb_dev); | 223 | wusb_dev_put(xfer->wusb_dev); |
| 233 | rpipe_put(xfer->ep->hcpriv); | 224 | rpipe_put(xfer->ep->hcpriv); |
| 234 | wa_xfer_giveback(xfer); | 225 | wa_xfer_giveback(xfer); |
| 235 | d_fnend(3, NULL, "(xfer %p) = void\n", xfer); | ||
| 236 | return; | ||
| 237 | } | 226 | } |
| 238 | 227 | ||
| 239 | /* | 228 | /* |
| @@ -243,12 +232,12 @@ static void wa_xfer_completion(struct wa_xfer *xfer) | |||
| 243 | */ | 232 | */ |
| 244 | static unsigned __wa_xfer_is_done(struct wa_xfer *xfer) | 233 | static unsigned __wa_xfer_is_done(struct wa_xfer *xfer) |
| 245 | { | 234 | { |
| 235 | struct device *dev = &xfer->wa->usb_iface->dev; | ||
| 246 | unsigned result, cnt; | 236 | unsigned result, cnt; |
| 247 | struct wa_seg *seg; | 237 | struct wa_seg *seg; |
| 248 | struct urb *urb = xfer->urb; | 238 | struct urb *urb = xfer->urb; |
| 249 | unsigned found_short = 0; | 239 | unsigned found_short = 0; |
| 250 | 240 | ||
| 251 | d_fnstart(3, NULL, "(xfer %p)\n", xfer); | ||
| 252 | result = xfer->segs_done == xfer->segs_submitted; | 241 | result = xfer->segs_done == xfer->segs_submitted; |
| 253 | if (result == 0) | 242 | if (result == 0) |
| 254 | goto out; | 243 | goto out; |
| @@ -258,10 +247,8 @@ static unsigned __wa_xfer_is_done(struct wa_xfer *xfer) | |||
| 258 | switch (seg->status) { | 247 | switch (seg->status) { |
| 259 | case WA_SEG_DONE: | 248 | case WA_SEG_DONE: |
| 260 | if (found_short && seg->result > 0) { | 249 | if (found_short && seg->result > 0) { |
| 261 | if (printk_ratelimit()) | 250 | dev_dbg(dev, "xfer %p#%u: bad short segments (%zu)\n", |
| 262 | printk(KERN_ERR "xfer %p#%u: bad short " | 251 | xfer, cnt, seg->result); |
| 263 | "segments (%zu)\n", xfer, cnt, | ||
| 264 | seg->result); | ||
| 265 | urb->status = -EINVAL; | 252 | urb->status = -EINVAL; |
| 266 | goto out; | 253 | goto out; |
| 267 | } | 254 | } |
| @@ -269,36 +256,30 @@ static unsigned __wa_xfer_is_done(struct wa_xfer *xfer) | |||
| 269 | if (seg->result < xfer->seg_size | 256 | if (seg->result < xfer->seg_size |
| 270 | && cnt != xfer->segs-1) | 257 | && cnt != xfer->segs-1) |
| 271 | found_short = 1; | 258 | found_short = 1; |
| 272 | d_printf(2, NULL, "xfer %p#%u: DONE short %d " | 259 | dev_dbg(dev, "xfer %p#%u: DONE short %d " |
| 273 | "result %zu urb->actual_length %d\n", | 260 | "result %zu urb->actual_length %d\n", |
| 274 | xfer, seg->index, found_short, seg->result, | 261 | xfer, seg->index, found_short, seg->result, |
| 275 | urb->actual_length); | 262 | urb->actual_length); |
| 276 | break; | 263 | break; |
| 277 | case WA_SEG_ERROR: | 264 | case WA_SEG_ERROR: |
| 278 | xfer->result = seg->result; | 265 | xfer->result = seg->result; |
| 279 | d_printf(2, NULL, "xfer %p#%u: ERROR result %zu\n", | 266 | dev_dbg(dev, "xfer %p#%u: ERROR result %zu\n", |
| 280 | xfer, seg->index, seg->result); | 267 | xfer, seg->index, seg->result); |
| 281 | goto out; | 268 | goto out; |
| 282 | case WA_SEG_ABORTED: | 269 | case WA_SEG_ABORTED: |
| 283 | WARN_ON(urb->status != -ECONNRESET | 270 | dev_dbg(dev, "xfer %p#%u ABORTED: result %d\n", |
| 284 | && urb->status != -ENOENT); | 271 | xfer, seg->index, urb->status); |
| 285 | d_printf(2, NULL, "xfer %p#%u ABORTED: result %d\n", | ||
| 286 | xfer, seg->index, urb->status); | ||
| 287 | xfer->result = urb->status; | 272 | xfer->result = urb->status; |
| 288 | goto out; | 273 | goto out; |
| 289 | default: | 274 | default: |
| 290 | /* if (printk_ratelimit()) */ | 275 | dev_warn(dev, "xfer %p#%u: is_done bad state %d\n", |
| 291 | printk(KERN_ERR "xfer %p#%u: " | 276 | xfer, cnt, seg->status); |
| 292 | "is_done bad state %d\n", | ||
| 293 | xfer, cnt, seg->status); | ||
| 294 | xfer->result = -EINVAL; | 277 | xfer->result = -EINVAL; |
| 295 | WARN_ON(1); | ||
| 296 | goto out; | 278 | goto out; |
| 297 | } | 279 | } |
| 298 | } | 280 | } |
| 299 | xfer->result = 0; | 281 | xfer->result = 0; |
| 300 | out: | 282 | out: |
| 301 | d_fnend(3, NULL, "(xfer %p) = void\n", xfer); | ||
| 302 | return result; | 283 | return result; |
| 303 | } | 284 | } |
| 304 | 285 | ||
| @@ -424,8 +405,6 @@ static ssize_t __wa_xfer_setup_sizes(struct wa_xfer *xfer, | |||
| 424 | struct urb *urb = xfer->urb; | 405 | struct urb *urb = xfer->urb; |
| 425 | struct wa_rpipe *rpipe = xfer->ep->hcpriv; | 406 | struct wa_rpipe *rpipe = xfer->ep->hcpriv; |
| 426 | 407 | ||
| 427 | d_fnstart(3, dev, "(xfer %p [rpipe %p] urb %p)\n", | ||
| 428 | xfer, rpipe, urb); | ||
| 429 | switch (rpipe->descr.bmAttribute & 0x3) { | 408 | switch (rpipe->descr.bmAttribute & 0x3) { |
| 430 | case USB_ENDPOINT_XFER_CONTROL: | 409 | case USB_ENDPOINT_XFER_CONTROL: |
| 431 | *pxfer_type = WA_XFER_TYPE_CTL; | 410 | *pxfer_type = WA_XFER_TYPE_CTL; |
| @@ -472,12 +451,10 @@ static ssize_t __wa_xfer_setup_sizes(struct wa_xfer *xfer, | |||
| 472 | if (xfer->segs == 0 && *pxfer_type == WA_XFER_TYPE_CTL) | 451 | if (xfer->segs == 0 && *pxfer_type == WA_XFER_TYPE_CTL) |
| 473 | xfer->segs = 1; | 452 | xfer->segs = 1; |
| 474 | error: | 453 | error: |
| 475 | d_fnend(3, dev, "(xfer %p [rpipe %p] urb %p) = %d\n", | ||
| 476 | xfer, rpipe, urb, (int)result); | ||
| 477 | return result; | 454 | return result; |
| 478 | } | 455 | } |
| 479 | 456 | ||
| 480 | /** Fill in the common request header and xfer-type specific data. */ | 457 | /* Fill in the common request header and xfer-type specific data. */ |
| 481 | static void __wa_xfer_setup_hdr0(struct wa_xfer *xfer, | 458 | static void __wa_xfer_setup_hdr0(struct wa_xfer *xfer, |
| 482 | struct wa_xfer_hdr *xfer_hdr0, | 459 | struct wa_xfer_hdr *xfer_hdr0, |
| 483 | enum wa_xfer_type xfer_type, | 460 | enum wa_xfer_type xfer_type, |
| @@ -534,14 +511,13 @@ static void wa_seg_dto_cb(struct urb *urb) | |||
| 534 | unsigned rpipe_ready = 0; | 511 | unsigned rpipe_ready = 0; |
| 535 | u8 done = 0; | 512 | u8 done = 0; |
| 536 | 513 | ||
| 537 | d_fnstart(3, NULL, "(urb %p [%d])\n", urb, urb->status); | ||
| 538 | switch (urb->status) { | 514 | switch (urb->status) { |
| 539 | case 0: | 515 | case 0: |
| 540 | spin_lock_irqsave(&xfer->lock, flags); | 516 | spin_lock_irqsave(&xfer->lock, flags); |
| 541 | wa = xfer->wa; | 517 | wa = xfer->wa; |
| 542 | dev = &wa->usb_iface->dev; | 518 | dev = &wa->usb_iface->dev; |
| 543 | d_printf(2, dev, "xfer %p#%u: data out done (%d bytes)\n", | 519 | dev_dbg(dev, "xfer %p#%u: data out done (%d bytes)\n", |
| 544 | xfer, seg->index, urb->actual_length); | 520 | xfer, seg->index, urb->actual_length); |
| 545 | if (seg->status < WA_SEG_PENDING) | 521 | if (seg->status < WA_SEG_PENDING) |
| 546 | seg->status = WA_SEG_PENDING; | 522 | seg->status = WA_SEG_PENDING; |
| 547 | seg->result = urb->actual_length; | 523 | seg->result = urb->actual_length; |
| @@ -555,9 +531,8 @@ static void wa_seg_dto_cb(struct urb *urb) | |||
| 555 | wa = xfer->wa; | 531 | wa = xfer->wa; |
| 556 | dev = &wa->usb_iface->dev; | 532 | dev = &wa->usb_iface->dev; |
| 557 | rpipe = xfer->ep->hcpriv; | 533 | rpipe = xfer->ep->hcpriv; |
| 558 | if (printk_ratelimit()) | 534 | dev_dbg(dev, "xfer %p#%u: data out error %d\n", |
| 559 | dev_err(dev, "xfer %p#%u: data out error %d\n", | 535 | xfer, seg->index, urb->status); |
| 560 | xfer, seg->index, urb->status); | ||
| 561 | if (edc_inc(&wa->nep_edc, EDC_MAX_ERRORS, | 536 | if (edc_inc(&wa->nep_edc, EDC_MAX_ERRORS, |
| 562 | EDC_ERROR_TIMEFRAME)){ | 537 | EDC_ERROR_TIMEFRAME)){ |
| 563 | dev_err(dev, "DTO: URB max acceptable errors " | 538 | dev_err(dev, "DTO: URB max acceptable errors " |
| @@ -578,7 +553,6 @@ static void wa_seg_dto_cb(struct urb *urb) | |||
| 578 | if (rpipe_ready) | 553 | if (rpipe_ready) |
| 579 | wa_xfer_delayed_run(rpipe); | 554 | wa_xfer_delayed_run(rpipe); |
| 580 | } | 555 | } |
| 581 | d_fnend(3, NULL, "(urb %p [%d]) = void\n", urb, urb->status); | ||
| 582 | } | 556 | } |
| 583 | 557 | ||
| 584 | /* | 558 | /* |
| @@ -610,14 +584,12 @@ static void wa_seg_cb(struct urb *urb) | |||
| 610 | unsigned rpipe_ready; | 584 | unsigned rpipe_ready; |
| 611 | u8 done = 0; | 585 | u8 done = 0; |
| 612 | 586 | ||
| 613 | d_fnstart(3, NULL, "(urb %p [%d])\n", urb, urb->status); | ||
| 614 | switch (urb->status) { | 587 | switch (urb->status) { |
| 615 | case 0: | 588 | case 0: |
| 616 | spin_lock_irqsave(&xfer->lock, flags); | 589 | spin_lock_irqsave(&xfer->lock, flags); |
| 617 | wa = xfer->wa; | 590 | wa = xfer->wa; |
| 618 | dev = &wa->usb_iface->dev; | 591 | dev = &wa->usb_iface->dev; |
| 619 | d_printf(2, dev, "xfer %p#%u: request done\n", | 592 | dev_dbg(dev, "xfer %p#%u: request done\n", xfer, seg->index); |
| 620 | xfer, seg->index); | ||
| 621 | if (xfer->is_inbound && seg->status < WA_SEG_PENDING) | 593 | if (xfer->is_inbound && seg->status < WA_SEG_PENDING) |
| 622 | seg->status = WA_SEG_PENDING; | 594 | seg->status = WA_SEG_PENDING; |
| 623 | spin_unlock_irqrestore(&xfer->lock, flags); | 595 | spin_unlock_irqrestore(&xfer->lock, flags); |
| @@ -652,7 +624,6 @@ static void wa_seg_cb(struct urb *urb) | |||
| 652 | if (rpipe_ready) | 624 | if (rpipe_ready) |
| 653 | wa_xfer_delayed_run(rpipe); | 625 | wa_xfer_delayed_run(rpipe); |
| 654 | } | 626 | } |
| 655 | d_fnend(3, NULL, "(urb %p [%d]) = void\n", urb, urb->status); | ||
| 656 | } | 627 | } |
| 657 | 628 | ||
| 658 | /* | 629 | /* |
| @@ -750,9 +721,6 @@ static int __wa_xfer_setup(struct wa_xfer *xfer, struct urb *urb) | |||
| 750 | size_t xfer_hdr_size, cnt, transfer_size; | 721 | size_t xfer_hdr_size, cnt, transfer_size; |
| 751 | struct wa_xfer_hdr *xfer_hdr0, *xfer_hdr; | 722 | struct wa_xfer_hdr *xfer_hdr0, *xfer_hdr; |
| 752 | 723 | ||
| 753 | d_fnstart(3, dev, "(xfer %p [rpipe %p] urb %p)\n", | ||
| 754 | xfer, xfer->ep->hcpriv, urb); | ||
| 755 | |||
| 756 | result = __wa_xfer_setup_sizes(xfer, &xfer_type); | 724 | result = __wa_xfer_setup_sizes(xfer, &xfer_type); |
| 757 | if (result < 0) | 725 | if (result < 0) |
| 758 | goto error_setup_sizes; | 726 | goto error_setup_sizes; |
| @@ -788,8 +756,6 @@ static int __wa_xfer_setup(struct wa_xfer *xfer, struct urb *urb) | |||
| 788 | result = 0; | 756 | result = 0; |
| 789 | error_setup_segs: | 757 | error_setup_segs: |
| 790 | error_setup_sizes: | 758 | error_setup_sizes: |
| 791 | d_fnend(3, dev, "(xfer %p [rpipe %p] urb %p) = %d\n", | ||
| 792 | xfer, xfer->ep->hcpriv, urb, result); | ||
| 793 | return result; | 759 | return result; |
| 794 | } | 760 | } |
| 795 | 761 | ||
| @@ -843,9 +809,6 @@ static void wa_xfer_delayed_run(struct wa_rpipe *rpipe) | |||
| 843 | struct wa_xfer *xfer; | 809 | struct wa_xfer *xfer; |
| 844 | unsigned long flags; | 810 | unsigned long flags; |
| 845 | 811 | ||
| 846 | d_fnstart(1, dev, "(rpipe #%d) %d segments available\n", | ||
| 847 | le16_to_cpu(rpipe->descr.wRPipeIndex), | ||
| 848 | atomic_read(&rpipe->segs_available)); | ||
| 849 | spin_lock_irqsave(&rpipe->seg_lock, flags); | 812 | spin_lock_irqsave(&rpipe->seg_lock, flags); |
| 850 | while (atomic_read(&rpipe->segs_available) > 0 | 813 | while (atomic_read(&rpipe->segs_available) > 0 |
| 851 | && !list_empty(&rpipe->seg_list)) { | 814 | && !list_empty(&rpipe->seg_list)) { |
| @@ -854,10 +817,8 @@ static void wa_xfer_delayed_run(struct wa_rpipe *rpipe) | |||
| 854 | list_del(&seg->list_node); | 817 | list_del(&seg->list_node); |
| 855 | xfer = seg->xfer; | 818 | xfer = seg->xfer; |
| 856 | result = __wa_seg_submit(rpipe, xfer, seg); | 819 | result = __wa_seg_submit(rpipe, xfer, seg); |
| 857 | d_printf(1, dev, "xfer %p#%u submitted from delayed " | 820 | dev_dbg(dev, "xfer %p#%u submitted from delayed [%d segments available] %d\n", |
| 858 | "[%d segments available] %d\n", | 821 | xfer, seg->index, atomic_read(&rpipe->segs_available), result); |
| 859 | xfer, seg->index, | ||
| 860 | atomic_read(&rpipe->segs_available), result); | ||
| 861 | if (unlikely(result < 0)) { | 822 | if (unlikely(result < 0)) { |
| 862 | spin_unlock_irqrestore(&rpipe->seg_lock, flags); | 823 | spin_unlock_irqrestore(&rpipe->seg_lock, flags); |
| 863 | spin_lock_irqsave(&xfer->lock, flags); | 824 | spin_lock_irqsave(&xfer->lock, flags); |
| @@ -868,10 +829,6 @@ static void wa_xfer_delayed_run(struct wa_rpipe *rpipe) | |||
| 868 | } | 829 | } |
| 869 | } | 830 | } |
| 870 | spin_unlock_irqrestore(&rpipe->seg_lock, flags); | 831 | spin_unlock_irqrestore(&rpipe->seg_lock, flags); |
| 871 | d_fnend(1, dev, "(rpipe #%d) = void, %d segments available\n", | ||
| 872 | le16_to_cpu(rpipe->descr.wRPipeIndex), | ||
| 873 | atomic_read(&rpipe->segs_available)); | ||
| 874 | |||
| 875 | } | 832 | } |
| 876 | 833 | ||
| 877 | /* | 834 | /* |
| @@ -894,9 +851,6 @@ static int __wa_xfer_submit(struct wa_xfer *xfer) | |||
| 894 | u8 available; | 851 | u8 available; |
| 895 | u8 empty; | 852 | u8 empty; |
| 896 | 853 | ||
| 897 | d_fnstart(3, dev, "(xfer %p [rpipe %p])\n", | ||
| 898 | xfer, xfer->ep->hcpriv); | ||
| 899 | |||
| 900 | spin_lock_irqsave(&wa->xfer_list_lock, flags); | 854 | spin_lock_irqsave(&wa->xfer_list_lock, flags); |
| 901 | list_add_tail(&xfer->list_node, &wa->xfer_list); | 855 | list_add_tail(&xfer->list_node, &wa->xfer_list); |
| 902 | spin_unlock_irqrestore(&wa->xfer_list_lock, flags); | 856 | spin_unlock_irqrestore(&wa->xfer_list_lock, flags); |
| @@ -908,30 +862,24 @@ static int __wa_xfer_submit(struct wa_xfer *xfer) | |||
| 908 | available = atomic_read(&rpipe->segs_available); | 862 | available = atomic_read(&rpipe->segs_available); |
| 909 | empty = list_empty(&rpipe->seg_list); | 863 | empty = list_empty(&rpipe->seg_list); |
| 910 | seg = xfer->seg[cnt]; | 864 | seg = xfer->seg[cnt]; |
| 911 | d_printf(2, dev, "xfer %p#%u: available %u empty %u (%s)\n", | 865 | dev_dbg(dev, "xfer %p#%u: available %u empty %u (%s)\n", |
| 912 | xfer, cnt, available, empty, | 866 | xfer, cnt, available, empty, |
| 913 | available == 0 || !empty ? "delayed" : "submitted"); | 867 | available == 0 || !empty ? "delayed" : "submitted"); |
| 914 | if (available == 0 || !empty) { | 868 | if (available == 0 || !empty) { |
| 915 | d_printf(1, dev, "xfer %p#%u: delayed\n", xfer, cnt); | 869 | dev_dbg(dev, "xfer %p#%u: delayed\n", xfer, cnt); |
| 916 | seg->status = WA_SEG_DELAYED; | 870 | seg->status = WA_SEG_DELAYED; |
| 917 | list_add_tail(&seg->list_node, &rpipe->seg_list); | 871 | list_add_tail(&seg->list_node, &rpipe->seg_list); |
| 918 | } else { | 872 | } else { |
| 919 | result = __wa_seg_submit(rpipe, xfer, seg); | 873 | result = __wa_seg_submit(rpipe, xfer, seg); |
| 920 | if (result < 0) | 874 | if (result < 0) { |
| 875 | __wa_xfer_abort(xfer); | ||
| 921 | goto error_seg_submit; | 876 | goto error_seg_submit; |
| 877 | } | ||
| 922 | } | 878 | } |
| 923 | xfer->segs_submitted++; | 879 | xfer->segs_submitted++; |
| 924 | } | 880 | } |
| 925 | spin_unlock_irqrestore(&rpipe->seg_lock, flags); | ||
| 926 | d_fnend(3, dev, "(xfer %p [rpipe %p]) = void\n", xfer, | ||
| 927 | xfer->ep->hcpriv); | ||
| 928 | return result; | ||
| 929 | |||
| 930 | error_seg_submit: | 881 | error_seg_submit: |
| 931 | __wa_xfer_abort(xfer); | ||
| 932 | spin_unlock_irqrestore(&rpipe->seg_lock, flags); | 882 | spin_unlock_irqrestore(&rpipe->seg_lock, flags); |
| 933 | d_fnend(3, dev, "(xfer %p [rpipe %p]) = void\n", xfer, | ||
| 934 | xfer->ep->hcpriv); | ||
| 935 | return result; | 883 | return result; |
| 936 | } | 884 | } |
| 937 | 885 | ||
| @@ -964,11 +912,9 @@ static void wa_urb_enqueue_b(struct wa_xfer *xfer) | |||
| 964 | struct urb *urb = xfer->urb; | 912 | struct urb *urb = xfer->urb; |
| 965 | struct wahc *wa = xfer->wa; | 913 | struct wahc *wa = xfer->wa; |
| 966 | struct wusbhc *wusbhc = wa->wusb; | 914 | struct wusbhc *wusbhc = wa->wusb; |
| 967 | struct device *dev = &wa->usb_iface->dev; | ||
| 968 | struct wusb_dev *wusb_dev; | 915 | struct wusb_dev *wusb_dev; |
| 969 | unsigned done; | 916 | unsigned done; |
| 970 | 917 | ||
| 971 | d_fnstart(3, dev, "(wa %p urb %p)\n", wa, urb); | ||
| 972 | result = rpipe_get_by_ep(wa, xfer->ep, urb, xfer->gfp); | 918 | result = rpipe_get_by_ep(wa, xfer->ep, urb, xfer->gfp); |
| 973 | if (result < 0) | 919 | if (result < 0) |
| 974 | goto error_rpipe_get; | 920 | goto error_rpipe_get; |
| @@ -997,7 +943,6 @@ static void wa_urb_enqueue_b(struct wa_xfer *xfer) | |||
| 997 | if (result < 0) | 943 | if (result < 0) |
| 998 | goto error_xfer_submit; | 944 | goto error_xfer_submit; |
| 999 | spin_unlock_irqrestore(&xfer->lock, flags); | 945 | spin_unlock_irqrestore(&xfer->lock, flags); |
| 1000 | d_fnend(3, dev, "(wa %p urb %p) = void\n", wa, urb); | ||
| 1001 | return; | 946 | return; |
| 1002 | 947 | ||
| 1003 | /* this is basically wa_xfer_completion() broken up wa_xfer_giveback() | 948 | /* this is basically wa_xfer_completion() broken up wa_xfer_giveback() |
| @@ -1015,7 +960,6 @@ error_dev_gone: | |||
| 1015 | error_rpipe_get: | 960 | error_rpipe_get: |
| 1016 | xfer->result = result; | 961 | xfer->result = result; |
| 1017 | wa_xfer_giveback(xfer); | 962 | wa_xfer_giveback(xfer); |
| 1018 | d_fnend(3, dev, "(wa %p urb %p) = (void) %d\n", wa, urb, result); | ||
| 1019 | return; | 963 | return; |
| 1020 | 964 | ||
| 1021 | error_xfer_submit: | 965 | error_xfer_submit: |
| @@ -1024,8 +968,6 @@ error_xfer_submit: | |||
| 1024 | spin_unlock_irqrestore(&xfer->lock, flags); | 968 | spin_unlock_irqrestore(&xfer->lock, flags); |
| 1025 | if (done) | 969 | if (done) |
| 1026 | wa_xfer_completion(xfer); | 970 | wa_xfer_completion(xfer); |
| 1027 | d_fnend(3, dev, "(wa %p urb %p) = (void) %d\n", wa, urb, result); | ||
| 1028 | return; | ||
| 1029 | } | 971 | } |
| 1030 | 972 | ||
| 1031 | /* | 973 | /* |
| @@ -1041,11 +983,9 @@ error_xfer_submit: | |||
| 1041 | void wa_urb_enqueue_run(struct work_struct *ws) | 983 | void wa_urb_enqueue_run(struct work_struct *ws) |
| 1042 | { | 984 | { |
| 1043 | struct wahc *wa = container_of(ws, struct wahc, xfer_work); | 985 | struct wahc *wa = container_of(ws, struct wahc, xfer_work); |
| 1044 | struct device *dev = &wa->usb_iface->dev; | ||
| 1045 | struct wa_xfer *xfer, *next; | 986 | struct wa_xfer *xfer, *next; |
| 1046 | struct urb *urb; | 987 | struct urb *urb; |
| 1047 | 988 | ||
| 1048 | d_fnstart(3, dev, "(wa %p)\n", wa); | ||
| 1049 | spin_lock_irq(&wa->xfer_list_lock); | 989 | spin_lock_irq(&wa->xfer_list_lock); |
| 1050 | list_for_each_entry_safe(xfer, next, &wa->xfer_delayed_list, | 990 | list_for_each_entry_safe(xfer, next, &wa->xfer_delayed_list, |
| 1051 | list_node) { | 991 | list_node) { |
| @@ -1059,7 +999,6 @@ void wa_urb_enqueue_run(struct work_struct *ws) | |||
| 1059 | spin_lock_irq(&wa->xfer_list_lock); | 999 | spin_lock_irq(&wa->xfer_list_lock); |
| 1060 | } | 1000 | } |
| 1061 | spin_unlock_irq(&wa->xfer_list_lock); | 1001 | spin_unlock_irq(&wa->xfer_list_lock); |
| 1062 | d_fnend(3, dev, "(wa %p) = void\n", wa); | ||
| 1063 | } | 1002 | } |
| 1064 | EXPORT_SYMBOL_GPL(wa_urb_enqueue_run); | 1003 | EXPORT_SYMBOL_GPL(wa_urb_enqueue_run); |
| 1065 | 1004 | ||
| @@ -1084,9 +1023,6 @@ int wa_urb_enqueue(struct wahc *wa, struct usb_host_endpoint *ep, | |||
| 1084 | unsigned long my_flags; | 1023 | unsigned long my_flags; |
| 1085 | unsigned cant_sleep = irqs_disabled() | in_atomic(); | 1024 | unsigned cant_sleep = irqs_disabled() | in_atomic(); |
| 1086 | 1025 | ||
| 1087 | d_fnstart(3, dev, "(wa %p ep %p urb %p [%d] gfp 0x%x)\n", | ||
| 1088 | wa, ep, urb, urb->transfer_buffer_length, gfp); | ||
| 1089 | |||
| 1090 | if (urb->transfer_buffer == NULL | 1026 | if (urb->transfer_buffer == NULL |
| 1091 | && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP) | 1027 | && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP) |
| 1092 | && urb->transfer_buffer_length != 0) { | 1028 | && urb->transfer_buffer_length != 0) { |
| @@ -1108,11 +1044,13 @@ int wa_urb_enqueue(struct wahc *wa, struct usb_host_endpoint *ep, | |||
| 1108 | xfer->gfp = gfp; | 1044 | xfer->gfp = gfp; |
| 1109 | xfer->ep = ep; | 1045 | xfer->ep = ep; |
| 1110 | urb->hcpriv = xfer; | 1046 | urb->hcpriv = xfer; |
| 1111 | d_printf(2, dev, "xfer %p urb %p pipe 0x%02x [%d bytes] %s %s %s\n", | 1047 | |
| 1112 | xfer, urb, urb->pipe, urb->transfer_buffer_length, | 1048 | dev_dbg(dev, "xfer %p urb %p pipe 0x%02x [%d bytes] %s %s %s\n", |
| 1113 | urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP ? "dma" : "nodma", | 1049 | xfer, urb, urb->pipe, urb->transfer_buffer_length, |
| 1114 | urb->pipe & USB_DIR_IN ? "inbound" : "outbound", | 1050 | urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP ? "dma" : "nodma", |
| 1115 | cant_sleep ? "deferred" : "inline"); | 1051 | urb->pipe & USB_DIR_IN ? "inbound" : "outbound", |
| 1052 | cant_sleep ? "deferred" : "inline"); | ||
| 1053 | |||
| 1116 | if (cant_sleep) { | 1054 | if (cant_sleep) { |
| 1117 | usb_get_urb(urb); | 1055 | usb_get_urb(urb); |
| 1118 | spin_lock_irqsave(&wa->xfer_list_lock, my_flags); | 1056 | spin_lock_irqsave(&wa->xfer_list_lock, my_flags); |
| @@ -1122,15 +1060,11 @@ int wa_urb_enqueue(struct wahc *wa, struct usb_host_endpoint *ep, | |||
| 1122 | } else { | 1060 | } else { |
| 1123 | wa_urb_enqueue_b(xfer); | 1061 | wa_urb_enqueue_b(xfer); |
| 1124 | } | 1062 | } |
| 1125 | d_fnend(3, dev, "(wa %p ep %p urb %p [%d] gfp 0x%x) = 0\n", | ||
| 1126 | wa, ep, urb, urb->transfer_buffer_length, gfp); | ||
| 1127 | return 0; | 1063 | return 0; |
| 1128 | 1064 | ||
| 1129 | error_dequeued: | 1065 | error_dequeued: |
| 1130 | kfree(xfer); | 1066 | kfree(xfer); |
| 1131 | error_kmalloc: | 1067 | error_kmalloc: |
| 1132 | d_fnend(3, dev, "(wa %p ep %p urb %p [%d] gfp 0x%x) = %d\n", | ||
| 1133 | wa, ep, urb, urb->transfer_buffer_length, gfp, result); | ||
| 1134 | return result; | 1068 | return result; |
| 1135 | } | 1069 | } |
| 1136 | EXPORT_SYMBOL_GPL(wa_urb_enqueue); | 1070 | EXPORT_SYMBOL_GPL(wa_urb_enqueue); |
| @@ -1155,7 +1089,6 @@ EXPORT_SYMBOL_GPL(wa_urb_enqueue); | |||
| 1155 | */ | 1089 | */ |
| 1156 | int wa_urb_dequeue(struct wahc *wa, struct urb *urb) | 1090 | int wa_urb_dequeue(struct wahc *wa, struct urb *urb) |
| 1157 | { | 1091 | { |
| 1158 | struct device *dev = &wa->usb_iface->dev; | ||
| 1159 | unsigned long flags, flags2; | 1092 | unsigned long flags, flags2; |
| 1160 | struct wa_xfer *xfer; | 1093 | struct wa_xfer *xfer; |
| 1161 | struct wa_seg *seg; | 1094 | struct wa_seg *seg; |
| @@ -1163,9 +1096,6 @@ int wa_urb_dequeue(struct wahc *wa, struct urb *urb) | |||
| 1163 | unsigned cnt; | 1096 | unsigned cnt; |
| 1164 | unsigned rpipe_ready = 0; | 1097 | unsigned rpipe_ready = 0; |
| 1165 | 1098 | ||
| 1166 | d_fnstart(3, dev, "(wa %p, urb %p)\n", wa, urb); | ||
| 1167 | |||
| 1168 | d_printf(1, dev, "xfer %p urb %p: aborting\n", urb->hcpriv, urb); | ||
| 1169 | xfer = urb->hcpriv; | 1099 | xfer = urb->hcpriv; |
| 1170 | if (xfer == NULL) { | 1100 | if (xfer == NULL) { |
| 1171 | /* NOthing setup yet enqueue will see urb->status != | 1101 | /* NOthing setup yet enqueue will see urb->status != |
| @@ -1234,13 +1164,11 @@ int wa_urb_dequeue(struct wahc *wa, struct urb *urb) | |||
| 1234 | wa_xfer_completion(xfer); | 1164 | wa_xfer_completion(xfer); |
| 1235 | if (rpipe_ready) | 1165 | if (rpipe_ready) |
| 1236 | wa_xfer_delayed_run(rpipe); | 1166 | wa_xfer_delayed_run(rpipe); |
| 1237 | d_fnend(3, dev, "(wa %p, urb %p) = 0\n", wa, urb); | ||
| 1238 | return 0; | 1167 | return 0; |
| 1239 | 1168 | ||
| 1240 | out_unlock: | 1169 | out_unlock: |
| 1241 | spin_unlock_irqrestore(&xfer->lock, flags); | 1170 | spin_unlock_irqrestore(&xfer->lock, flags); |
| 1242 | out: | 1171 | out: |
| 1243 | d_fnend(3, dev, "(wa %p, urb %p) = 0\n", wa, urb); | ||
| 1244 | return 0; | 1172 | return 0; |
| 1245 | 1173 | ||
| 1246 | dequeue_delayed: | 1174 | dequeue_delayed: |
| @@ -1250,7 +1178,6 @@ dequeue_delayed: | |||
| 1250 | spin_unlock_irqrestore(&xfer->lock, flags); | 1178 | spin_unlock_irqrestore(&xfer->lock, flags); |
| 1251 | wa_xfer_giveback(xfer); | 1179 | wa_xfer_giveback(xfer); |
| 1252 | usb_put_urb(urb); /* we got a ref in enqueue() */ | 1180 | usb_put_urb(urb); /* we got a ref in enqueue() */ |
| 1253 | d_fnend(3, dev, "(wa %p, urb %p) = 0\n", wa, urb); | ||
| 1254 | return 0; | 1181 | return 0; |
| 1255 | } | 1182 | } |
| 1256 | EXPORT_SYMBOL_GPL(wa_urb_dequeue); | 1183 | EXPORT_SYMBOL_GPL(wa_urb_dequeue); |
| @@ -1326,7 +1253,6 @@ static void wa_xfer_result_chew(struct wahc *wa, struct wa_xfer *xfer) | |||
| 1326 | u8 usb_status; | 1253 | u8 usb_status; |
| 1327 | unsigned rpipe_ready = 0; | 1254 | unsigned rpipe_ready = 0; |
| 1328 | 1255 | ||
| 1329 | d_fnstart(3, dev, "(wa %p xfer %p)\n", wa, xfer); | ||
| 1330 | spin_lock_irqsave(&xfer->lock, flags); | 1256 | spin_lock_irqsave(&xfer->lock, flags); |
| 1331 | seg_idx = xfer_result->bTransferSegment & 0x7f; | 1257 | seg_idx = xfer_result->bTransferSegment & 0x7f; |
| 1332 | if (unlikely(seg_idx >= xfer->segs)) | 1258 | if (unlikely(seg_idx >= xfer->segs)) |
| @@ -1334,8 +1260,8 @@ static void wa_xfer_result_chew(struct wahc *wa, struct wa_xfer *xfer) | |||
| 1334 | seg = xfer->seg[seg_idx]; | 1260 | seg = xfer->seg[seg_idx]; |
| 1335 | rpipe = xfer->ep->hcpriv; | 1261 | rpipe = xfer->ep->hcpriv; |
| 1336 | usb_status = xfer_result->bTransferStatus; | 1262 | usb_status = xfer_result->bTransferStatus; |
| 1337 | d_printf(2, dev, "xfer %p#%u: bTransferStatus 0x%02x (seg %u)\n", | 1263 | dev_dbg(dev, "xfer %p#%u: bTransferStatus 0x%02x (seg %u)\n", |
| 1338 | xfer, seg_idx, usb_status, seg->status); | 1264 | xfer, seg_idx, usb_status, seg->status); |
| 1339 | if (seg->status == WA_SEG_ABORTED | 1265 | if (seg->status == WA_SEG_ABORTED |
| 1340 | || seg->status == WA_SEG_ERROR) /* already handled */ | 1266 | || seg->status == WA_SEG_ERROR) /* already handled */ |
| 1341 | goto segment_aborted; | 1267 | goto segment_aborted; |
| @@ -1391,10 +1317,8 @@ static void wa_xfer_result_chew(struct wahc *wa, struct wa_xfer *xfer) | |||
| 1391 | wa_xfer_completion(xfer); | 1317 | wa_xfer_completion(xfer); |
| 1392 | if (rpipe_ready) | 1318 | if (rpipe_ready) |
| 1393 | wa_xfer_delayed_run(rpipe); | 1319 | wa_xfer_delayed_run(rpipe); |
| 1394 | d_fnend(3, dev, "(wa %p xfer %p) = void\n", wa, xfer); | ||
| 1395 | return; | 1320 | return; |
| 1396 | 1321 | ||
| 1397 | |||
| 1398 | error_submit_buf_in: | 1322 | error_submit_buf_in: |
| 1399 | if (edc_inc(&wa->dti_edc, EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) { | 1323 | if (edc_inc(&wa->dti_edc, EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) { |
| 1400 | dev_err(dev, "DTI: URB max acceptable errors " | 1324 | dev_err(dev, "DTI: URB max acceptable errors " |
| @@ -1416,11 +1340,8 @@ error_complete: | |||
| 1416 | wa_xfer_completion(xfer); | 1340 | wa_xfer_completion(xfer); |
| 1417 | if (rpipe_ready) | 1341 | if (rpipe_ready) |
| 1418 | wa_xfer_delayed_run(rpipe); | 1342 | wa_xfer_delayed_run(rpipe); |
| 1419 | d_fnend(3, dev, "(wa %p xfer %p) = void [segment/DTI-submit error]\n", | ||
| 1420 | wa, xfer); | ||
| 1421 | return; | 1343 | return; |
| 1422 | 1344 | ||
| 1423 | |||
| 1424 | error_bad_seg: | 1345 | error_bad_seg: |
| 1425 | spin_unlock_irqrestore(&xfer->lock, flags); | 1346 | spin_unlock_irqrestore(&xfer->lock, flags); |
| 1426 | wa_urb_dequeue(wa, xfer->urb); | 1347 | wa_urb_dequeue(wa, xfer->urb); |
| @@ -1431,17 +1352,11 @@ error_bad_seg: | |||
| 1431 | "exceeded, resetting device\n"); | 1352 | "exceeded, resetting device\n"); |
| 1432 | wa_reset_all(wa); | 1353 | wa_reset_all(wa); |
| 1433 | } | 1354 | } |
| 1434 | d_fnend(3, dev, "(wa %p xfer %p) = void [bad seg]\n", wa, xfer); | ||
| 1435 | return; | 1355 | return; |
| 1436 | 1356 | ||
| 1437 | |||
| 1438 | segment_aborted: | 1357 | segment_aborted: |
| 1439 | /* nothing to do, as the aborter did the completion */ | 1358 | /* nothing to do, as the aborter did the completion */ |
| 1440 | spin_unlock_irqrestore(&xfer->lock, flags); | 1359 | spin_unlock_irqrestore(&xfer->lock, flags); |
| 1441 | d_fnend(3, dev, "(wa %p xfer %p) = void [segment aborted]\n", | ||
| 1442 | wa, xfer); | ||
| 1443 | return; | ||
| 1444 | |||
| 1445 | } | 1360 | } |
| 1446 | 1361 | ||
| 1447 | /* | 1362 | /* |
| @@ -1465,15 +1380,14 @@ static void wa_buf_in_cb(struct urb *urb) | |||
| 1465 | unsigned long flags; | 1380 | unsigned long flags; |
| 1466 | u8 done = 0; | 1381 | u8 done = 0; |
| 1467 | 1382 | ||
| 1468 | d_fnstart(3, NULL, "(urb %p [%d])\n", urb, urb->status); | ||
| 1469 | switch (urb->status) { | 1383 | switch (urb->status) { |
| 1470 | case 0: | 1384 | case 0: |
| 1471 | spin_lock_irqsave(&xfer->lock, flags); | 1385 | spin_lock_irqsave(&xfer->lock, flags); |
| 1472 | wa = xfer->wa; | 1386 | wa = xfer->wa; |
| 1473 | dev = &wa->usb_iface->dev; | 1387 | dev = &wa->usb_iface->dev; |
| 1474 | rpipe = xfer->ep->hcpriv; | 1388 | rpipe = xfer->ep->hcpriv; |
| 1475 | d_printf(2, dev, "xfer %p#%u: data in done (%zu bytes)\n", | 1389 | dev_dbg(dev, "xfer %p#%u: data in done (%zu bytes)\n", |
| 1476 | xfer, seg->index, (size_t)urb->actual_length); | 1390 | xfer, seg->index, (size_t)urb->actual_length); |
| 1477 | seg->status = WA_SEG_DONE; | 1391 | seg->status = WA_SEG_DONE; |
| 1478 | seg->result = urb->actual_length; | 1392 | seg->result = urb->actual_length; |
| 1479 | xfer->segs_done++; | 1393 | xfer->segs_done++; |
| @@ -1514,7 +1428,6 @@ static void wa_buf_in_cb(struct urb *urb) | |||
| 1514 | if (rpipe_ready) | 1428 | if (rpipe_ready) |
| 1515 | wa_xfer_delayed_run(rpipe); | 1429 | wa_xfer_delayed_run(rpipe); |
| 1516 | } | 1430 | } |
| 1517 | d_fnend(3, NULL, "(urb %p [%d]) = void\n", urb, urb->status); | ||
| 1518 | } | 1431 | } |
| 1519 | 1432 | ||
| 1520 | /* | 1433 | /* |
| @@ -1553,14 +1466,12 @@ static void wa_xfer_result_cb(struct urb *urb) | |||
| 1553 | struct wa_xfer *xfer; | 1466 | struct wa_xfer *xfer; |
| 1554 | u8 usb_status; | 1467 | u8 usb_status; |
| 1555 | 1468 | ||
| 1556 | d_fnstart(3, dev, "(%p)\n", wa); | ||
| 1557 | BUG_ON(wa->dti_urb != urb); | 1469 | BUG_ON(wa->dti_urb != urb); |
| 1558 | switch (wa->dti_urb->status) { | 1470 | switch (wa->dti_urb->status) { |
| 1559 | case 0: | 1471 | case 0: |
| 1560 | /* We have a xfer result buffer; check it */ | 1472 | /* We have a xfer result buffer; check it */ |
| 1561 | d_printf(2, dev, "DTI: xfer result %d bytes at %p\n", | 1473 | dev_dbg(dev, "DTI: xfer result %d bytes at %p\n", |
| 1562 | urb->actual_length, urb->transfer_buffer); | 1474 | urb->actual_length, urb->transfer_buffer); |
| 1563 | d_dump(3, dev, urb->transfer_buffer, urb->actual_length); | ||
| 1564 | if (wa->dti_urb->actual_length != sizeof(*xfer_result)) { | 1475 | if (wa->dti_urb->actual_length != sizeof(*xfer_result)) { |
| 1565 | dev_err(dev, "DTI Error: xfer result--bad size " | 1476 | dev_err(dev, "DTI Error: xfer result--bad size " |
| 1566 | "xfer result (%d bytes vs %zu needed)\n", | 1477 | "xfer result (%d bytes vs %zu needed)\n", |
| @@ -1622,7 +1533,6 @@ static void wa_xfer_result_cb(struct urb *urb) | |||
| 1622 | wa_reset_all(wa); | 1533 | wa_reset_all(wa); |
| 1623 | } | 1534 | } |
| 1624 | out: | 1535 | out: |
| 1625 | d_fnend(3, dev, "(%p) = void\n", wa); | ||
| 1626 | return; | 1536 | return; |
| 1627 | } | 1537 | } |
| 1628 | 1538 | ||
| @@ -1653,7 +1563,6 @@ void wa_handle_notif_xfer(struct wahc *wa, struct wa_notif_hdr *notif_hdr) | |||
| 1653 | struct wa_notif_xfer *notif_xfer; | 1563 | struct wa_notif_xfer *notif_xfer; |
| 1654 | const struct usb_endpoint_descriptor *dti_epd = wa->dti_epd; | 1564 | const struct usb_endpoint_descriptor *dti_epd = wa->dti_epd; |
| 1655 | 1565 | ||
| 1656 | d_fnstart(4, dev, "(%p, %p)\n", wa, notif_hdr); | ||
| 1657 | notif_xfer = container_of(notif_hdr, struct wa_notif_xfer, hdr); | 1566 | notif_xfer = container_of(notif_hdr, struct wa_notif_xfer, hdr); |
| 1658 | BUG_ON(notif_hdr->bNotifyType != WA_NOTIF_TRANSFER); | 1567 | BUG_ON(notif_hdr->bNotifyType != WA_NOTIF_TRANSFER); |
| 1659 | 1568 | ||
| @@ -1693,7 +1602,6 @@ void wa_handle_notif_xfer(struct wahc *wa, struct wa_notif_hdr *notif_hdr) | |||
| 1693 | goto error_dti_urb_submit; | 1602 | goto error_dti_urb_submit; |
| 1694 | } | 1603 | } |
| 1695 | out: | 1604 | out: |
| 1696 | d_fnend(4, dev, "(%p, %p) = void\n", wa, notif_hdr); | ||
| 1697 | return; | 1605 | return; |
| 1698 | 1606 | ||
| 1699 | error_dti_urb_submit: | 1607 | error_dti_urb_submit: |
| @@ -1704,6 +1612,4 @@ error_buf_in_urb_alloc: | |||
| 1704 | error_dti_urb_alloc: | 1612 | error_dti_urb_alloc: |
| 1705 | error: | 1613 | error: |
| 1706 | wa_reset_all(wa); | 1614 | wa_reset_all(wa); |
| 1707 | d_fnend(4, dev, "(%p, %p) = void\n", wa, notif_hdr); | ||
| 1708 | return; | ||
| 1709 | } | 1615 | } |
diff --git a/drivers/usb/wusbcore/wusbhc.h b/drivers/usb/wusbcore/wusbhc.h index d0c132434f1..797c2453a35 100644 --- a/drivers/usb/wusbcore/wusbhc.h +++ b/drivers/usb/wusbcore/wusbhc.h | |||
| @@ -64,6 +64,13 @@ | |||
| 64 | #include <linux/uwb.h> | 64 | #include <linux/uwb.h> |
| 65 | #include <linux/usb/wusb.h> | 65 | #include <linux/usb/wusb.h> |
| 66 | 66 | ||
| 67 | /* | ||
| 68 | * Time from a WUSB channel stop request to the last transmitted MMC. | ||
| 69 | * | ||
| 70 | * This needs to be > 4.096 ms in case no MMCs can be transmitted in | ||
| 71 | * zone 0. | ||
| 72 | */ | ||
| 73 | #define WUSB_CHANNEL_STOP_DELAY_MS 8 | ||
| 67 | 74 | ||
| 68 | /** | 75 | /** |
| 69 | * Wireless USB device | 76 | * Wireless USB device |
| @@ -147,7 +154,6 @@ struct wusb_port { | |||
| 147 | u16 status; | 154 | u16 status; |
| 148 | u16 change; | 155 | u16 change; |
| 149 | struct wusb_dev *wusb_dev; /* connected device's info */ | 156 | struct wusb_dev *wusb_dev; /* connected device's info */ |
| 150 | unsigned reset_count; | ||
| 151 | u32 ptk_tkid; | 157 | u32 ptk_tkid; |
| 152 | }; | 158 | }; |
| 153 | 159 | ||
| @@ -198,21 +204,18 @@ struct wusb_port { | |||
| 198 | * @mmcies_max Max number of Information Elements this HC can send | 204 | * @mmcies_max Max number of Information Elements this HC can send |
| 199 | * in its MMC. Read-only. | 205 | * in its MMC. Read-only. |
| 200 | * | 206 | * |
| 207 | * @start Start the WUSB channel. | ||
| 208 | * | ||
| 209 | * @stop Stop the WUSB channel after the specified number of | ||
| 210 | * milliseconds. Channel Stop IEs should be transmitted | ||
| 211 | * as required by [WUSB] 4.16.2.1. | ||
| 212 | * | ||
| 201 | * @mmcie_add HC specific operation (WHCI or HWA) for adding an | 213 | * @mmcie_add HC specific operation (WHCI or HWA) for adding an |
| 202 | * MMCIE. | 214 | * MMCIE. |
| 203 | * | 215 | * |
| 204 | * @mmcie_rm HC specific operation (WHCI or HWA) for removing an | 216 | * @mmcie_rm HC specific operation (WHCI or HWA) for removing an |
| 205 | * MMCIE. | 217 | * MMCIE. |
| 206 | * | 218 | * |
| 207 | * @enc_types Array which describes the encryptions methods | ||
| 208 | * supported by the host as described in WUSB1.0 -- | ||
| 209 | * one entry per supported method. As of WUSB1.0 there | ||
| 210 | * is only four methods, we make space for eight just in | ||
| 211 | * case they decide to add some more (and pray they do | ||
| 212 | * it in sequential order). if 'enc_types[enc_method] | ||
| 213 | * != 0', then it is supported by the host. enc_method | ||
| 214 | * is USB_ENC_TYPE*. | ||
| 215 | * | ||
| 216 | * @set_ptk: Set the PTK and enable encryption for a device. Or, if | 219 | * @set_ptk: Set the PTK and enable encryption for a device. Or, if |
| 217 | * the supplied key is NULL, disable encryption for that | 220 | * the supplied key is NULL, disable encryption for that |
| 218 | * device. | 221 | * device. |
| @@ -249,7 +252,8 @@ struct wusbhc { | |||
| 249 | struct uwb_pal pal; | 252 | struct uwb_pal pal; |
| 250 | 253 | ||
| 251 | unsigned trust_timeout; /* in jiffies */ | 254 | unsigned trust_timeout; /* in jiffies */ |
| 252 | struct wuie_host_info *wuie_host_info; /* Includes CHID */ | 255 | struct wusb_ckhdid chid; |
| 256 | struct wuie_host_info *wuie_host_info; | ||
| 253 | 257 | ||
| 254 | struct mutex mutex; /* locks everything else */ | 258 | struct mutex mutex; /* locks everything else */ |
| 255 | u16 cluster_id; /* Wireless USB Cluster ID */ | 259 | u16 cluster_id; /* Wireless USB Cluster ID */ |
| @@ -269,7 +273,7 @@ struct wusbhc { | |||
| 269 | u8 mmcies_max; | 273 | u8 mmcies_max; |
| 270 | /* FIXME: make wusbhc_ops? */ | 274 | /* FIXME: make wusbhc_ops? */ |
| 271 | int (*start)(struct wusbhc *wusbhc); | 275 | int (*start)(struct wusbhc *wusbhc); |
| 272 | void (*stop)(struct wusbhc *wusbhc); | 276 | void (*stop)(struct wusbhc *wusbhc, int delay); |
| 273 | int (*mmcie_add)(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt, | 277 | int (*mmcie_add)(struct wusbhc *wusbhc, u8 interval, u8 repeat_cnt, |
| 274 | u8 handle, struct wuie_hdr *wuie); | 278 | u8 handle, struct wuie_hdr *wuie); |
| 275 | int (*mmcie_rm)(struct wusbhc *wusbhc, u8 handle); | 279 | int (*mmcie_rm)(struct wusbhc *wusbhc, u8 handle); |
| @@ -373,20 +377,17 @@ static inline void wusbhc_put(struct wusbhc *wusbhc) | |||
| 373 | usb_put_hcd(&wusbhc->usb_hcd); | 377 | usb_put_hcd(&wusbhc->usb_hcd); |
| 374 | } | 378 | } |
| 375 | 379 | ||
| 376 | int wusbhc_start(struct wusbhc *wusbhc, const struct wusb_ckhdid *chid); | 380 | int wusbhc_start(struct wusbhc *wusbhc); |
| 377 | void wusbhc_stop(struct wusbhc *wusbhc); | 381 | void wusbhc_stop(struct wusbhc *wusbhc); |
| 378 | extern int wusbhc_chid_set(struct wusbhc *, const struct wusb_ckhdid *); | 382 | extern int wusbhc_chid_set(struct wusbhc *, const struct wusb_ckhdid *); |
| 379 | 383 | ||
| 380 | /* Device connect handling */ | 384 | /* Device connect handling */ |
| 381 | extern int wusbhc_devconnect_create(struct wusbhc *); | 385 | extern int wusbhc_devconnect_create(struct wusbhc *); |
| 382 | extern void wusbhc_devconnect_destroy(struct wusbhc *); | 386 | extern void wusbhc_devconnect_destroy(struct wusbhc *); |
| 383 | extern int wusbhc_devconnect_start(struct wusbhc *wusbhc, | 387 | extern int wusbhc_devconnect_start(struct wusbhc *wusbhc); |
| 384 | const struct wusb_ckhdid *chid); | ||
| 385 | extern void wusbhc_devconnect_stop(struct wusbhc *wusbhc); | 388 | extern void wusbhc_devconnect_stop(struct wusbhc *wusbhc); |
| 386 | extern int wusbhc_devconnect_auth(struct wusbhc *, u8); | ||
| 387 | extern void wusbhc_handle_dn(struct wusbhc *, u8 srcaddr, | 389 | extern void wusbhc_handle_dn(struct wusbhc *, u8 srcaddr, |
| 388 | struct wusb_dn_hdr *dn_hdr, size_t size); | 390 | struct wusb_dn_hdr *dn_hdr, size_t size); |
| 389 | extern int wusbhc_dev_reset(struct wusbhc *wusbhc, u8 port); | ||
| 390 | extern void __wusbhc_dev_disable(struct wusbhc *wusbhc, u8 port); | 391 | extern void __wusbhc_dev_disable(struct wusbhc *wusbhc, u8 port); |
| 391 | extern int wusb_usb_ncb(struct notifier_block *nb, unsigned long val, | 392 | extern int wusb_usb_ncb(struct notifier_block *nb, unsigned long val, |
| 392 | void *priv); | 393 | void *priv); |
| @@ -432,6 +433,7 @@ extern void wusb_dev_sec_rm(struct wusb_dev *) ; | |||
| 432 | extern int wusb_dev_4way_handshake(struct wusbhc *, struct wusb_dev *, | 433 | extern int wusb_dev_4way_handshake(struct wusbhc *, struct wusb_dev *, |
| 433 | struct wusb_ckhdid *ck); | 434 | struct wusb_ckhdid *ck); |
| 434 | void wusbhc_gtk_rekey(struct wusbhc *wusbhc); | 435 | void wusbhc_gtk_rekey(struct wusbhc *wusbhc); |
| 436 | int wusb_dev_update_address(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev); | ||
| 435 | 437 | ||
| 436 | 438 | ||
| 437 | /* WUSB Cluster ID handling */ | 439 | /* WUSB Cluster ID handling */ |
diff --git a/drivers/uwb/Makefile b/drivers/uwb/Makefile index 257e6908304..2f98d080fe7 100644 --- a/drivers/uwb/Makefile +++ b/drivers/uwb/Makefile | |||
| @@ -6,6 +6,7 @@ obj-$(CONFIG_UWB_I1480U) += i1480/ | |||
| 6 | 6 | ||
| 7 | uwb-objs := \ | 7 | uwb-objs := \ |
| 8 | address.o \ | 8 | address.o \ |
| 9 | allocator.o \ | ||
| 9 | beacon.o \ | 10 | beacon.o \ |
| 10 | driver.o \ | 11 | driver.o \ |
| 11 | drp.o \ | 12 | drp.o \ |
| @@ -13,10 +14,12 @@ uwb-objs := \ | |||
| 13 | drp-ie.o \ | 14 | drp-ie.o \ |
| 14 | est.o \ | 15 | est.o \ |
| 15 | ie.o \ | 16 | ie.o \ |
| 17 | ie-rcv.o \ | ||
| 16 | lc-dev.o \ | 18 | lc-dev.o \ |
| 17 | lc-rc.o \ | 19 | lc-rc.o \ |
| 18 | neh.o \ | 20 | neh.o \ |
| 19 | pal.o \ | 21 | pal.o \ |
| 22 | radio.o \ | ||
| 20 | reset.o \ | 23 | reset.o \ |
| 21 | rsv.o \ | 24 | rsv.o \ |
| 22 | scan.o \ | 25 | scan.o \ |
diff --git a/drivers/uwb/address.c b/drivers/uwb/address.c index 1664ae5f170..ad21b1d7218 100644 --- a/drivers/uwb/address.c +++ b/drivers/uwb/address.c | |||
| @@ -28,7 +28,7 @@ | |||
| 28 | #include <linux/device.h> | 28 | #include <linux/device.h> |
| 29 | #include <linux/random.h> | 29 | #include <linux/random.h> |
| 30 | #include <linux/etherdevice.h> | 30 | #include <linux/etherdevice.h> |
| 31 | #include <linux/uwb/debug.h> | 31 | |
| 32 | #include "uwb-internal.h" | 32 | #include "uwb-internal.h" |
| 33 | 33 | ||
| 34 | 34 | ||
diff --git a/drivers/uwb/allocator.c b/drivers/uwb/allocator.c new file mode 100644 index 00000000000..c8185e6b0cd --- /dev/null +++ b/drivers/uwb/allocator.c | |||
| @@ -0,0 +1,386 @@ | |||
| 1 | /* | ||
| 2 | * UWB reservation management. | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008 Cambridge Silicon Radio Ltd. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public License version | ||
| 8 | * 2 as published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 17 | */ | ||
| 18 | #include <linux/version.h> | ||
| 19 | #include <linux/kernel.h> | ||
| 20 | #include <linux/uwb.h> | ||
| 21 | |||
| 22 | #include "uwb-internal.h" | ||
| 23 | |||
| 24 | static void uwb_rsv_fill_column_alloc(struct uwb_rsv_alloc_info *ai) | ||
| 25 | { | ||
| 26 | int col, mas, safe_mas, unsafe_mas; | ||
| 27 | unsigned char *bm = ai->bm; | ||
| 28 | struct uwb_rsv_col_info *ci = ai->ci; | ||
| 29 | unsigned char c; | ||
| 30 | |||
| 31 | for (col = ci->csi.start_col; col < UWB_NUM_ZONES; col += ci->csi.interval) { | ||
| 32 | |||
| 33 | safe_mas = ci->csi.safe_mas_per_col; | ||
| 34 | unsafe_mas = ci->csi.unsafe_mas_per_col; | ||
| 35 | |||
| 36 | for (mas = 0; mas < UWB_MAS_PER_ZONE; mas++ ) { | ||
| 37 | if (bm[col * UWB_MAS_PER_ZONE + mas] == 0) { | ||
| 38 | |||
| 39 | if (safe_mas > 0) { | ||
| 40 | safe_mas--; | ||
| 41 | c = UWB_RSV_MAS_SAFE; | ||
| 42 | } else if (unsafe_mas > 0) { | ||
| 43 | unsafe_mas--; | ||
| 44 | c = UWB_RSV_MAS_UNSAFE; | ||
| 45 | } else { | ||
| 46 | break; | ||
| 47 | } | ||
| 48 | bm[col * UWB_MAS_PER_ZONE + mas] = c; | ||
| 49 | } | ||
| 50 | } | ||
| 51 | } | ||
| 52 | } | ||
| 53 | |||
| 54 | static void uwb_rsv_fill_row_alloc(struct uwb_rsv_alloc_info *ai) | ||
| 55 | { | ||
| 56 | int mas, col, rows; | ||
| 57 | unsigned char *bm = ai->bm; | ||
| 58 | struct uwb_rsv_row_info *ri = &ai->ri; | ||
| 59 | unsigned char c; | ||
| 60 | |||
| 61 | rows = 1; | ||
| 62 | c = UWB_RSV_MAS_SAFE; | ||
| 63 | for (mas = UWB_MAS_PER_ZONE - 1; mas >= 0; mas--) { | ||
| 64 | if (ri->avail[mas] == 1) { | ||
| 65 | |||
| 66 | if (rows > ri->used_rows) { | ||
| 67 | break; | ||
| 68 | } else if (rows > 7) { | ||
| 69 | c = UWB_RSV_MAS_UNSAFE; | ||
| 70 | } | ||
| 71 | |||
| 72 | for (col = 0; col < UWB_NUM_ZONES; col++) { | ||
| 73 | if (bm[col * UWB_NUM_ZONES + mas] != UWB_RSV_MAS_NOT_AVAIL) { | ||
| 74 | bm[col * UWB_NUM_ZONES + mas] = c; | ||
| 75 | if(c == UWB_RSV_MAS_SAFE) | ||
| 76 | ai->safe_allocated_mases++; | ||
| 77 | else | ||
| 78 | ai->unsafe_allocated_mases++; | ||
| 79 | } | ||
| 80 | } | ||
| 81 | rows++; | ||
| 82 | } | ||
| 83 | } | ||
| 84 | ai->total_allocated_mases = ai->safe_allocated_mases + ai->unsafe_allocated_mases; | ||
| 85 | } | ||
| 86 | |||
| 87 | /* | ||
| 88 | * Find the best column set for a given availability, interval, num safe mas and | ||
| 89 | * num unsafe mas. | ||
| 90 | * | ||
| 91 | * The different sets are tried in order as shown below, depending on the interval. | ||
| 92 | * | ||
| 93 | * interval = 16 | ||
| 94 | * deep = 0 | ||
| 95 | * set 1 -> { 8 } | ||
| 96 | * deep = 1 | ||
| 97 | * set 1 -> { 4 } | ||
| 98 | * set 2 -> { 12 } | ||
| 99 | * deep = 2 | ||
| 100 | * set 1 -> { 2 } | ||
| 101 | * set 2 -> { 6 } | ||
| 102 | * set 3 -> { 10 } | ||
| 103 | * set 4 -> { 14 } | ||
| 104 | * deep = 3 | ||
| 105 | * set 1 -> { 1 } | ||
| 106 | * set 2 -> { 3 } | ||
| 107 | * set 3 -> { 5 } | ||
| 108 | * set 4 -> { 7 } | ||
| 109 | * set 5 -> { 9 } | ||
| 110 | * set 6 -> { 11 } | ||
| 111 | * set 7 -> { 13 } | ||
| 112 | * set 8 -> { 15 } | ||
| 113 | * | ||
| 114 | * interval = 8 | ||
| 115 | * deep = 0 | ||
| 116 | * set 1 -> { 4 12 } | ||
| 117 | * deep = 1 | ||
| 118 | * set 1 -> { 2 10 } | ||
| 119 | * set 2 -> { 6 14 } | ||
| 120 | * deep = 2 | ||
| 121 | * set 1 -> { 1 9 } | ||
| 122 | * set 2 -> { 3 11 } | ||
| 123 | * set 3 -> { 5 13 } | ||
| 124 | * set 4 -> { 7 15 } | ||
| 125 | * | ||
| 126 | * interval = 4 | ||
| 127 | * deep = 0 | ||
| 128 | * set 1 -> { 2 6 10 14 } | ||
| 129 | * deep = 1 | ||
| 130 | * set 1 -> { 1 5 9 13 } | ||
| 131 | * set 2 -> { 3 7 11 15 } | ||
| 132 | * | ||
| 133 | * interval = 2 | ||
| 134 | * deep = 0 | ||
| 135 | * set 1 -> { 1 3 5 7 9 11 13 15 } | ||
| 136 | */ | ||
| 137 | static int uwb_rsv_find_best_column_set(struct uwb_rsv_alloc_info *ai, int interval, | ||
| 138 | int num_safe_mas, int num_unsafe_mas) | ||
| 139 | { | ||
| 140 | struct uwb_rsv_col_info *ci = ai->ci; | ||
| 141 | struct uwb_rsv_col_set_info *csi = &ci->csi; | ||
| 142 | struct uwb_rsv_col_set_info tmp_csi; | ||
| 143 | int deep, set, col, start_col_deep, col_start_set; | ||
| 144 | int start_col, max_mas_in_set, lowest_max_mas_in_deep; | ||
| 145 | int n_mas; | ||
| 146 | int found = UWB_RSV_ALLOC_NOT_FOUND; | ||
| 147 | |||
| 148 | tmp_csi.start_col = 0; | ||
| 149 | start_col_deep = interval; | ||
| 150 | n_mas = num_unsafe_mas + num_safe_mas; | ||
| 151 | |||
| 152 | for (deep = 0; ((interval >> deep) & 0x1) == 0; deep++) { | ||
| 153 | start_col_deep /= 2; | ||
| 154 | col_start_set = 0; | ||
| 155 | lowest_max_mas_in_deep = UWB_MAS_PER_ZONE; | ||
| 156 | |||
| 157 | for (set = 1; set <= (1 << deep); set++) { | ||
| 158 | max_mas_in_set = 0; | ||
| 159 | start_col = start_col_deep + col_start_set; | ||
| 160 | for (col = start_col; col < UWB_NUM_ZONES; col += interval) { | ||
| 161 | |||
| 162 | if (ci[col].max_avail_safe >= num_safe_mas && | ||
| 163 | ci[col].max_avail_unsafe >= n_mas) { | ||
| 164 | if (ci[col].highest_mas[n_mas] > max_mas_in_set) | ||
| 165 | max_mas_in_set = ci[col].highest_mas[n_mas]; | ||
| 166 | } else { | ||
| 167 | max_mas_in_set = 0; | ||
| 168 | break; | ||
| 169 | } | ||
| 170 | } | ||
| 171 | if ((lowest_max_mas_in_deep > max_mas_in_set) && max_mas_in_set) { | ||
| 172 | lowest_max_mas_in_deep = max_mas_in_set; | ||
| 173 | |||
| 174 | tmp_csi.start_col = start_col; | ||
| 175 | } | ||
| 176 | col_start_set += (interval >> deep); | ||
| 177 | } | ||
| 178 | |||
| 179 | if (lowest_max_mas_in_deep < 8) { | ||
| 180 | csi->start_col = tmp_csi.start_col; | ||
| 181 | found = UWB_RSV_ALLOC_FOUND; | ||
| 182 | break; | ||
| 183 | } else if ((lowest_max_mas_in_deep > 8) && | ||
| 184 | (lowest_max_mas_in_deep != UWB_MAS_PER_ZONE) && | ||
| 185 | (found == UWB_RSV_ALLOC_NOT_FOUND)) { | ||
| 186 | csi->start_col = tmp_csi.start_col; | ||
| 187 | found = UWB_RSV_ALLOC_FOUND; | ||
| 188 | } | ||
| 189 | } | ||
| 190 | |||
| 191 | if (found == UWB_RSV_ALLOC_FOUND) { | ||
| 192 | csi->interval = interval; | ||
| 193 | csi->safe_mas_per_col = num_safe_mas; | ||
| 194 | csi->unsafe_mas_per_col = num_unsafe_mas; | ||
| 195 | |||
| 196 | ai->safe_allocated_mases = (UWB_NUM_ZONES / interval) * num_safe_mas; | ||
| 197 | ai->unsafe_allocated_mases = (UWB_NUM_ZONES / interval) * num_unsafe_mas; | ||
| 198 | ai->total_allocated_mases = ai->safe_allocated_mases + ai->unsafe_allocated_mases; | ||
| 199 | ai->interval = interval; | ||
| 200 | } | ||
| 201 | return found; | ||
| 202 | } | ||
| 203 | |||
| 204 | static void get_row_descriptors(struct uwb_rsv_alloc_info *ai) | ||
| 205 | { | ||
| 206 | unsigned char *bm = ai->bm; | ||
| 207 | struct uwb_rsv_row_info *ri = &ai->ri; | ||
| 208 | int col, mas; | ||
| 209 | |||
| 210 | ri->free_rows = 16; | ||
| 211 | for (mas = 0; mas < UWB_MAS_PER_ZONE; mas ++) { | ||
| 212 | ri->avail[mas] = 1; | ||
| 213 | for (col = 1; col < UWB_NUM_ZONES; col++) { | ||
| 214 | if (bm[col * UWB_NUM_ZONES + mas] == UWB_RSV_MAS_NOT_AVAIL) { | ||
| 215 | ri->free_rows--; | ||
| 216 | ri->avail[mas]=0; | ||
| 217 | break; | ||
| 218 | } | ||
| 219 | } | ||
| 220 | } | ||
| 221 | } | ||
| 222 | |||
| 223 | static void uwb_rsv_fill_column_info(unsigned char *bm, int column, struct uwb_rsv_col_info *rci) | ||
| 224 | { | ||
| 225 | int mas; | ||
| 226 | int block_count = 0, start_block = 0; | ||
| 227 | int previous_avail = 0; | ||
| 228 | int available = 0; | ||
| 229 | int safe_mas_in_row[UWB_MAS_PER_ZONE] = { | ||
| 230 | 8, 7, 6, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 2, 1, | ||
| 231 | }; | ||
| 232 | |||
| 233 | rci->max_avail_safe = 0; | ||
| 234 | |||
| 235 | for (mas = 0; mas < UWB_MAS_PER_ZONE; mas ++) { | ||
| 236 | if (!bm[column * UWB_NUM_ZONES + mas]) { | ||
| 237 | available++; | ||
| 238 | rci->max_avail_unsafe = available; | ||
| 239 | |||
| 240 | rci->highest_mas[available] = mas; | ||
| 241 | |||
| 242 | if (previous_avail) { | ||
| 243 | block_count++; | ||
| 244 | if ((block_count > safe_mas_in_row[start_block]) && | ||
| 245 | (!rci->max_avail_safe)) | ||
| 246 | rci->max_avail_safe = available - 1; | ||
| 247 | } else { | ||
| 248 | previous_avail = 1; | ||
| 249 | start_block = mas; | ||
| 250 | block_count = 1; | ||
| 251 | } | ||
| 252 | } else { | ||
| 253 | previous_avail = 0; | ||
| 254 | } | ||
| 255 | } | ||
| 256 | if (!rci->max_avail_safe) | ||
| 257 | rci->max_avail_safe = rci->max_avail_unsafe; | ||
| 258 | } | ||
| 259 | |||
| 260 | static void get_column_descriptors(struct uwb_rsv_alloc_info *ai) | ||
| 261 | { | ||
| 262 | unsigned char *bm = ai->bm; | ||
| 263 | struct uwb_rsv_col_info *ci = ai->ci; | ||
| 264 | int col; | ||
| 265 | |||
| 266 | for (col = 1; col < UWB_NUM_ZONES; col++) { | ||
| 267 | uwb_rsv_fill_column_info(bm, col, &ci[col]); | ||
| 268 | } | ||
| 269 | } | ||
| 270 | |||
| 271 | static int uwb_rsv_find_best_row_alloc(struct uwb_rsv_alloc_info *ai) | ||
| 272 | { | ||
| 273 | int n_rows; | ||
| 274 | int max_rows = ai->max_mas / UWB_USABLE_MAS_PER_ROW; | ||
| 275 | int min_rows = ai->min_mas / UWB_USABLE_MAS_PER_ROW; | ||
| 276 | if (ai->min_mas % UWB_USABLE_MAS_PER_ROW) | ||
| 277 | min_rows++; | ||
| 278 | for (n_rows = max_rows; n_rows >= min_rows; n_rows--) { | ||
| 279 | if (n_rows <= ai->ri.free_rows) { | ||
| 280 | ai->ri.used_rows = n_rows; | ||
| 281 | ai->interval = 1; /* row reservation */ | ||
| 282 | uwb_rsv_fill_row_alloc(ai); | ||
| 283 | return UWB_RSV_ALLOC_FOUND; | ||
| 284 | } | ||
| 285 | } | ||
| 286 | return UWB_RSV_ALLOC_NOT_FOUND; | ||
| 287 | } | ||
| 288 | |||
| 289 | static int uwb_rsv_find_best_col_alloc(struct uwb_rsv_alloc_info *ai, int interval) | ||
| 290 | { | ||
| 291 | int n_safe, n_unsafe, n_mas; | ||
| 292 | int n_column = UWB_NUM_ZONES / interval; | ||
| 293 | int max_per_zone = ai->max_mas / n_column; | ||
| 294 | int min_per_zone = ai->min_mas / n_column; | ||
| 295 | |||
| 296 | if (ai->min_mas % n_column) | ||
| 297 | min_per_zone++; | ||
| 298 | |||
| 299 | if (min_per_zone > UWB_MAS_PER_ZONE) { | ||
| 300 | return UWB_RSV_ALLOC_NOT_FOUND; | ||
| 301 | } | ||
| 302 | |||
| 303 | if (max_per_zone > UWB_MAS_PER_ZONE) { | ||
| 304 | max_per_zone = UWB_MAS_PER_ZONE; | ||
| 305 | } | ||
| 306 | |||
| 307 | for (n_mas = max_per_zone; n_mas >= min_per_zone; n_mas--) { | ||
| 308 | if (uwb_rsv_find_best_column_set(ai, interval, 0, n_mas) == UWB_RSV_ALLOC_NOT_FOUND) | ||
| 309 | continue; | ||
| 310 | for (n_safe = n_mas; n_safe >= 0; n_safe--) { | ||
| 311 | n_unsafe = n_mas - n_safe; | ||
| 312 | if (uwb_rsv_find_best_column_set(ai, interval, n_safe, n_unsafe) == UWB_RSV_ALLOC_FOUND) { | ||
| 313 | uwb_rsv_fill_column_alloc(ai); | ||
| 314 | return UWB_RSV_ALLOC_FOUND; | ||
| 315 | } | ||
| 316 | } | ||
| 317 | } | ||
| 318 | return UWB_RSV_ALLOC_NOT_FOUND; | ||
| 319 | } | ||
| 320 | |||
| 321 | int uwb_rsv_find_best_allocation(struct uwb_rsv *rsv, struct uwb_mas_bm *available, | ||
| 322 | struct uwb_mas_bm *result) | ||
| 323 | { | ||
| 324 | struct uwb_rsv_alloc_info *ai; | ||
| 325 | int interval; | ||
| 326 | int bit_index; | ||
| 327 | |||
| 328 | ai = kzalloc(sizeof(struct uwb_rsv_alloc_info), GFP_KERNEL); | ||
| 329 | |||
| 330 | ai->min_mas = rsv->min_mas; | ||
| 331 | ai->max_mas = rsv->max_mas; | ||
| 332 | ai->max_interval = rsv->max_interval; | ||
| 333 | |||
| 334 | |||
| 335 | /* fill the not available vector from the available bm */ | ||
| 336 | for (bit_index = 0; bit_index < UWB_NUM_MAS; bit_index++) { | ||
| 337 | if (!test_bit(bit_index, available->bm)) | ||
| 338 | ai->bm[bit_index] = UWB_RSV_MAS_NOT_AVAIL; | ||
| 339 | } | ||
| 340 | |||
| 341 | if (ai->max_interval == 1) { | ||
| 342 | get_row_descriptors(ai); | ||
| 343 | if (uwb_rsv_find_best_row_alloc(ai) == UWB_RSV_ALLOC_FOUND) | ||
| 344 | goto alloc_found; | ||
| 345 | else | ||
| 346 | goto alloc_not_found; | ||
| 347 | } | ||
| 348 | |||
| 349 | get_column_descriptors(ai); | ||
| 350 | |||
| 351 | for (interval = 16; interval >= 2; interval>>=1) { | ||
| 352 | if (interval > ai->max_interval) | ||
| 353 | continue; | ||
| 354 | if (uwb_rsv_find_best_col_alloc(ai, interval) == UWB_RSV_ALLOC_FOUND) | ||
| 355 | goto alloc_found; | ||
| 356 | } | ||
| 357 | |||
| 358 | /* try row reservation if no column is found */ | ||
| 359 | get_row_descriptors(ai); | ||
| 360 | if (uwb_rsv_find_best_row_alloc(ai) == UWB_RSV_ALLOC_FOUND) | ||
| 361 | goto alloc_found; | ||
| 362 | else | ||
| 363 | goto alloc_not_found; | ||
| 364 | |||
| 365 | alloc_found: | ||
| 366 | bitmap_zero(result->bm, UWB_NUM_MAS); | ||
| 367 | bitmap_zero(result->unsafe_bm, UWB_NUM_MAS); | ||
| 368 | /* fill the safe and unsafe bitmaps */ | ||
| 369 | for (bit_index = 0; bit_index < UWB_NUM_MAS; bit_index++) { | ||
| 370 | if (ai->bm[bit_index] == UWB_RSV_MAS_SAFE) | ||
| 371 | set_bit(bit_index, result->bm); | ||
| 372 | else if (ai->bm[bit_index] == UWB_RSV_MAS_UNSAFE) | ||
| 373 | set_bit(bit_index, result->unsafe_bm); | ||
| 374 | } | ||
| 375 | bitmap_or(result->bm, result->bm, result->unsafe_bm, UWB_NUM_MAS); | ||
| 376 | |||
| 377 | result->safe = ai->safe_allocated_mases; | ||
| 378 | result->unsafe = ai->unsafe_allocated_mases; | ||
| 379 | |||
| 380 | kfree(ai); | ||
| 381 | return UWB_RSV_ALLOC_FOUND; | ||
| 382 | |||
| 383 | alloc_not_found: | ||
| 384 | kfree(ai); | ||
| 385 | return UWB_RSV_ALLOC_NOT_FOUND; | ||
| 386 | } | ||
diff --git a/drivers/uwb/beacon.c b/drivers/uwb/beacon.c index 46b18eec502..36bc3158006 100644 --- a/drivers/uwb/beacon.c +++ b/drivers/uwb/beacon.c | |||
| @@ -22,19 +22,16 @@ | |||
| 22 | * | 22 | * |
| 23 | * FIXME: docs | 23 | * FIXME: docs |
| 24 | */ | 24 | */ |
| 25 | |||
| 26 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
| 27 | #include <linux/init.h> | 26 | #include <linux/init.h> |
| 28 | #include <linux/module.h> | 27 | #include <linux/module.h> |
| 29 | #include <linux/device.h> | 28 | #include <linux/device.h> |
| 30 | #include <linux/err.h> | 29 | #include <linux/err.h> |
| 31 | #include <linux/kdev_t.h> | 30 | #include <linux/kdev_t.h> |
| 32 | #include "uwb-internal.h" | ||
| 33 | 31 | ||
| 34 | #define D_LOCAL 0 | 32 | #include "uwb-internal.h" |
| 35 | #include <linux/uwb/debug.h> | ||
| 36 | 33 | ||
| 37 | /** Start Beaconing command structure */ | 34 | /* Start Beaconing command structure */ |
| 38 | struct uwb_rc_cmd_start_beacon { | 35 | struct uwb_rc_cmd_start_beacon { |
| 39 | struct uwb_rccb rccb; | 36 | struct uwb_rccb rccb; |
| 40 | __le16 wBPSTOffset; | 37 | __le16 wBPSTOffset; |
| @@ -119,7 +116,6 @@ int uwb_rc_beacon(struct uwb_rc *rc, int channel, unsigned bpst_offset) | |||
| 119 | int result; | 116 | int result; |
| 120 | struct device *dev = &rc->uwb_dev.dev; | 117 | struct device *dev = &rc->uwb_dev.dev; |
| 121 | 118 | ||
| 122 | mutex_lock(&rc->uwb_dev.mutex); | ||
| 123 | if (channel < 0) | 119 | if (channel < 0) |
| 124 | channel = -1; | 120 | channel = -1; |
| 125 | if (channel == -1) | 121 | if (channel == -1) |
| @@ -128,7 +124,7 @@ int uwb_rc_beacon(struct uwb_rc *rc, int channel, unsigned bpst_offset) | |||
| 128 | /* channel >= 0...dah */ | 124 | /* channel >= 0...dah */ |
| 129 | result = uwb_rc_start_beacon(rc, bpst_offset, channel); | 125 | result = uwb_rc_start_beacon(rc, bpst_offset, channel); |
| 130 | if (result < 0) | 126 | if (result < 0) |
| 131 | goto out_up; | 127 | return result; |
| 132 | if (le16_to_cpu(rc->ies->wIELength) > 0) { | 128 | if (le16_to_cpu(rc->ies->wIELength) > 0) { |
| 133 | result = uwb_rc_set_ie(rc, rc->ies); | 129 | result = uwb_rc_set_ie(rc, rc->ies); |
| 134 | if (result < 0) { | 130 | if (result < 0) { |
| @@ -137,19 +133,12 @@ int uwb_rc_beacon(struct uwb_rc *rc, int channel, unsigned bpst_offset) | |||
| 137 | result = uwb_rc_stop_beacon(rc); | 133 | result = uwb_rc_stop_beacon(rc); |
| 138 | channel = -1; | 134 | channel = -1; |
| 139 | bpst_offset = 0; | 135 | bpst_offset = 0; |
| 140 | } else | 136 | } |
| 141 | result = 0; | ||
| 142 | } | 137 | } |
| 143 | } | 138 | } |
| 144 | 139 | ||
| 145 | if (result < 0) | 140 | if (result >= 0) |
| 146 | goto out_up; | 141 | rc->beaconing = channel; |
| 147 | rc->beaconing = channel; | ||
| 148 | |||
| 149 | uwb_notify(rc, NULL, uwb_bg_joined(rc) ? UWB_NOTIF_BG_JOIN : UWB_NOTIF_BG_LEAVE); | ||
| 150 | |||
| 151 | out_up: | ||
| 152 | mutex_unlock(&rc->uwb_dev.mutex); | ||
| 153 | return result; | 142 | return result; |
| 154 | } | 143 | } |
| 155 | 144 | ||
| @@ -168,12 +157,6 @@ out_up: | |||
| 168 | * FIXME: use something faster for search than a list | 157 | * FIXME: use something faster for search than a list |
| 169 | */ | 158 | */ |
| 170 | 159 | ||
| 171 | struct uwb_beca uwb_beca = { | ||
| 172 | .list = LIST_HEAD_INIT(uwb_beca.list), | ||
| 173 | .mutex = __MUTEX_INITIALIZER(uwb_beca.mutex) | ||
| 174 | }; | ||
| 175 | |||
| 176 | |||
| 177 | void uwb_bce_kfree(struct kref *_bce) | 160 | void uwb_bce_kfree(struct kref *_bce) |
| 178 | { | 161 | { |
| 179 | struct uwb_beca_e *bce = container_of(_bce, struct uwb_beca_e, refcnt); | 162 | struct uwb_beca_e *bce = container_of(_bce, struct uwb_beca_e, refcnt); |
| @@ -185,13 +168,11 @@ void uwb_bce_kfree(struct kref *_bce) | |||
| 185 | 168 | ||
| 186 | /* Find a beacon by dev addr in the cache */ | 169 | /* Find a beacon by dev addr in the cache */ |
| 187 | static | 170 | static |
| 188 | struct uwb_beca_e *__uwb_beca_find_bydev(const struct uwb_dev_addr *dev_addr) | 171 | struct uwb_beca_e *__uwb_beca_find_bydev(struct uwb_rc *rc, |
| 172 | const struct uwb_dev_addr *dev_addr) | ||
| 189 | { | 173 | { |
| 190 | struct uwb_beca_e *bce, *next; | 174 | struct uwb_beca_e *bce, *next; |
| 191 | list_for_each_entry_safe(bce, next, &uwb_beca.list, node) { | 175 | list_for_each_entry_safe(bce, next, &rc->uwb_beca.list, node) { |
| 192 | d_printf(6, NULL, "looking for addr %02x:%02x in %02x:%02x\n", | ||
| 193 | dev_addr->data[0], dev_addr->data[1], | ||
| 194 | bce->dev_addr.data[0], bce->dev_addr.data[1]); | ||
| 195 | if (!memcmp(&bce->dev_addr, dev_addr, sizeof(bce->dev_addr))) | 176 | if (!memcmp(&bce->dev_addr, dev_addr, sizeof(bce->dev_addr))) |
| 196 | goto out; | 177 | goto out; |
| 197 | } | 178 | } |
| @@ -202,10 +183,11 @@ out: | |||
| 202 | 183 | ||
| 203 | /* Find a beacon by dev addr in the cache */ | 184 | /* Find a beacon by dev addr in the cache */ |
| 204 | static | 185 | static |
| 205 | struct uwb_beca_e *__uwb_beca_find_bymac(const struct uwb_mac_addr *mac_addr) | 186 | struct uwb_beca_e *__uwb_beca_find_bymac(struct uwb_rc *rc, |
| 187 | const struct uwb_mac_addr *mac_addr) | ||
| 206 | { | 188 | { |
| 207 | struct uwb_beca_e *bce, *next; | 189 | struct uwb_beca_e *bce, *next; |
| 208 | list_for_each_entry_safe(bce, next, &uwb_beca.list, node) { | 190 | list_for_each_entry_safe(bce, next, &rc->uwb_beca.list, node) { |
| 209 | if (!memcmp(bce->mac_addr, mac_addr->data, | 191 | if (!memcmp(bce->mac_addr, mac_addr->data, |
| 210 | sizeof(struct uwb_mac_addr))) | 192 | sizeof(struct uwb_mac_addr))) |
| 211 | goto out; | 193 | goto out; |
| @@ -229,11 +211,11 @@ struct uwb_dev *uwb_dev_get_by_devaddr(struct uwb_rc *rc, | |||
| 229 | struct uwb_dev *found = NULL; | 211 | struct uwb_dev *found = NULL; |
| 230 | struct uwb_beca_e *bce; | 212 | struct uwb_beca_e *bce; |
| 231 | 213 | ||
| 232 | mutex_lock(&uwb_beca.mutex); | 214 | mutex_lock(&rc->uwb_beca.mutex); |
| 233 | bce = __uwb_beca_find_bydev(devaddr); | 215 | bce = __uwb_beca_find_bydev(rc, devaddr); |
| 234 | if (bce) | 216 | if (bce) |
| 235 | found = uwb_dev_try_get(rc, bce->uwb_dev); | 217 | found = uwb_dev_try_get(rc, bce->uwb_dev); |
| 236 | mutex_unlock(&uwb_beca.mutex); | 218 | mutex_unlock(&rc->uwb_beca.mutex); |
| 237 | 219 | ||
| 238 | return found; | 220 | return found; |
| 239 | } | 221 | } |
| @@ -249,11 +231,11 @@ struct uwb_dev *uwb_dev_get_by_macaddr(struct uwb_rc *rc, | |||
| 249 | struct uwb_dev *found = NULL; | 231 | struct uwb_dev *found = NULL; |
| 250 | struct uwb_beca_e *bce; | 232 | struct uwb_beca_e *bce; |
| 251 | 233 | ||
| 252 | mutex_lock(&uwb_beca.mutex); | 234 | mutex_lock(&rc->uwb_beca.mutex); |
| 253 | bce = __uwb_beca_find_bymac(macaddr); | 235 | bce = __uwb_beca_find_bymac(rc, macaddr); |
| 254 | if (bce) | 236 | if (bce) |
| 255 | found = uwb_dev_try_get(rc, bce->uwb_dev); | 237 | found = uwb_dev_try_get(rc, bce->uwb_dev); |
| 256 | mutex_unlock(&uwb_beca.mutex); | 238 | mutex_unlock(&rc->uwb_beca.mutex); |
| 257 | 239 | ||
| 258 | return found; | 240 | return found; |
| 259 | } | 241 | } |
| @@ -274,7 +256,9 @@ static void uwb_beca_e_init(struct uwb_beca_e *bce) | |||
| 274 | * @bf: Beacon frame (part of b, really) | 256 | * @bf: Beacon frame (part of b, really) |
| 275 | * @ts_jiffies: Timestamp (in jiffies) when the beacon was received | 257 | * @ts_jiffies: Timestamp (in jiffies) when the beacon was received |
| 276 | */ | 258 | */ |
| 277 | struct uwb_beca_e *__uwb_beca_add(struct uwb_rc_evt_beacon *be, | 259 | static |
| 260 | struct uwb_beca_e *__uwb_beca_add(struct uwb_rc *rc, | ||
| 261 | struct uwb_rc_evt_beacon *be, | ||
| 278 | struct uwb_beacon_frame *bf, | 262 | struct uwb_beacon_frame *bf, |
| 279 | unsigned long ts_jiffies) | 263 | unsigned long ts_jiffies) |
| 280 | { | 264 | { |
| @@ -286,7 +270,7 @@ struct uwb_beca_e *__uwb_beca_add(struct uwb_rc_evt_beacon *be, | |||
| 286 | uwb_beca_e_init(bce); | 270 | uwb_beca_e_init(bce); |
| 287 | bce->ts_jiffies = ts_jiffies; | 271 | bce->ts_jiffies = ts_jiffies; |
| 288 | bce->uwb_dev = NULL; | 272 | bce->uwb_dev = NULL; |
| 289 | list_add(&bce->node, &uwb_beca.list); | 273 | list_add(&bce->node, &rc->uwb_beca.list); |
| 290 | return bce; | 274 | return bce; |
| 291 | } | 275 | } |
| 292 | 276 | ||
| @@ -295,33 +279,32 @@ struct uwb_beca_e *__uwb_beca_add(struct uwb_rc_evt_beacon *be, | |||
| 295 | * | 279 | * |
| 296 | * Remove associated devicest too. | 280 | * Remove associated devicest too. |
| 297 | */ | 281 | */ |
| 298 | void uwb_beca_purge(void) | 282 | void uwb_beca_purge(struct uwb_rc *rc) |
| 299 | { | 283 | { |
| 300 | struct uwb_beca_e *bce, *next; | 284 | struct uwb_beca_e *bce, *next; |
| 301 | unsigned long expires; | 285 | unsigned long expires; |
| 302 | 286 | ||
| 303 | mutex_lock(&uwb_beca.mutex); | 287 | mutex_lock(&rc->uwb_beca.mutex); |
| 304 | list_for_each_entry_safe(bce, next, &uwb_beca.list, node) { | 288 | list_for_each_entry_safe(bce, next, &rc->uwb_beca.list, node) { |
| 305 | expires = bce->ts_jiffies + msecs_to_jiffies(beacon_timeout_ms); | 289 | expires = bce->ts_jiffies + msecs_to_jiffies(beacon_timeout_ms); |
| 306 | if (time_after(jiffies, expires)) { | 290 | if (time_after(jiffies, expires)) { |
| 307 | uwbd_dev_offair(bce); | 291 | uwbd_dev_offair(bce); |
| 308 | list_del(&bce->node); | ||
| 309 | uwb_bce_put(bce); | ||
| 310 | } | 292 | } |
| 311 | } | 293 | } |
| 312 | mutex_unlock(&uwb_beca.mutex); | 294 | mutex_unlock(&rc->uwb_beca.mutex); |
| 313 | } | 295 | } |
| 314 | 296 | ||
| 315 | /* Clean up the whole beacon cache. Called on shutdown */ | 297 | /* Clean up the whole beacon cache. Called on shutdown */ |
| 316 | void uwb_beca_release(void) | 298 | void uwb_beca_release(struct uwb_rc *rc) |
| 317 | { | 299 | { |
| 318 | struct uwb_beca_e *bce, *next; | 300 | struct uwb_beca_e *bce, *next; |
| 319 | mutex_lock(&uwb_beca.mutex); | 301 | |
| 320 | list_for_each_entry_safe(bce, next, &uwb_beca.list, node) { | 302 | mutex_lock(&rc->uwb_beca.mutex); |
| 303 | list_for_each_entry_safe(bce, next, &rc->uwb_beca.list, node) { | ||
| 321 | list_del(&bce->node); | 304 | list_del(&bce->node); |
| 322 | uwb_bce_put(bce); | 305 | uwb_bce_put(bce); |
| 323 | } | 306 | } |
| 324 | mutex_unlock(&uwb_beca.mutex); | 307 | mutex_unlock(&rc->uwb_beca.mutex); |
| 325 | } | 308 | } |
| 326 | 309 | ||
| 327 | static void uwb_beacon_print(struct uwb_rc *rc, struct uwb_rc_evt_beacon *be, | 310 | static void uwb_beacon_print(struct uwb_rc *rc, struct uwb_rc_evt_beacon *be, |
| @@ -349,22 +332,22 @@ ssize_t uwb_bce_print_IEs(struct uwb_dev *uwb_dev, struct uwb_beca_e *bce, | |||
| 349 | ssize_t result = 0; | 332 | ssize_t result = 0; |
| 350 | struct uwb_rc_evt_beacon *be; | 333 | struct uwb_rc_evt_beacon *be; |
| 351 | struct uwb_beacon_frame *bf; | 334 | struct uwb_beacon_frame *bf; |
| 352 | struct uwb_buf_ctx ctx = { | 335 | int ies_len; |
| 353 | .buf = buf, | 336 | struct uwb_ie_hdr *ies; |
| 354 | .bytes = 0, | ||
| 355 | .size = size | ||
| 356 | }; | ||
| 357 | 337 | ||
| 358 | mutex_lock(&bce->mutex); | 338 | mutex_lock(&bce->mutex); |
| 339 | |||
| 359 | be = bce->be; | 340 | be = bce->be; |
| 360 | if (be == NULL) | 341 | if (be) { |
| 361 | goto out; | 342 | bf = (struct uwb_beacon_frame *)bce->be->BeaconInfo; |
| 362 | bf = (void *) be->BeaconInfo; | 343 | ies_len = be->wBeaconInfoLength - sizeof(struct uwb_beacon_frame); |
| 363 | uwb_ie_for_each(uwb_dev, uwb_ie_dump_hex, &ctx, | 344 | ies = (struct uwb_ie_hdr *)bf->IEData; |
| 364 | bf->IEData, be->wBeaconInfoLength - sizeof(*bf)); | 345 | |
| 365 | result = ctx.bytes; | 346 | result = uwb_ie_dump_hex(ies, ies_len, buf, size); |
| 366 | out: | 347 | } |
| 348 | |||
| 367 | mutex_unlock(&bce->mutex); | 349 | mutex_unlock(&bce->mutex); |
| 350 | |||
| 368 | return result; | 351 | return result; |
| 369 | } | 352 | } |
| 370 | 353 | ||
| @@ -437,18 +420,18 @@ int uwbd_evt_handle_rc_beacon(struct uwb_event *evt) | |||
| 437 | if (uwb_mac_addr_bcast(&bf->Device_Identifier)) | 420 | if (uwb_mac_addr_bcast(&bf->Device_Identifier)) |
| 438 | return 0; | 421 | return 0; |
| 439 | 422 | ||
| 440 | mutex_lock(&uwb_beca.mutex); | 423 | mutex_lock(&rc->uwb_beca.mutex); |
| 441 | bce = __uwb_beca_find_bymac(&bf->Device_Identifier); | 424 | bce = __uwb_beca_find_bymac(rc, &bf->Device_Identifier); |
| 442 | if (bce == NULL) { | 425 | if (bce == NULL) { |
| 443 | /* Not in there, a new device is pinging */ | 426 | /* Not in there, a new device is pinging */ |
| 444 | uwb_beacon_print(evt->rc, be, bf); | 427 | uwb_beacon_print(evt->rc, be, bf); |
| 445 | bce = __uwb_beca_add(be, bf, evt->ts_jiffies); | 428 | bce = __uwb_beca_add(rc, be, bf, evt->ts_jiffies); |
| 446 | if (bce == NULL) { | 429 | if (bce == NULL) { |
| 447 | mutex_unlock(&uwb_beca.mutex); | 430 | mutex_unlock(&rc->uwb_beca.mutex); |
| 448 | return -ENOMEM; | 431 | return -ENOMEM; |
| 449 | } | 432 | } |
| 450 | } | 433 | } |
| 451 | mutex_unlock(&uwb_beca.mutex); | 434 | mutex_unlock(&rc->uwb_beca.mutex); |
| 452 | 435 | ||
| 453 | mutex_lock(&bce->mutex); | 436 | mutex_lock(&bce->mutex); |
| 454 | /* purge old beacon data */ | 437 | /* purge old beacon data */ |
| @@ -588,19 +571,6 @@ error: | |||
| 588 | return result; | 571 | return result; |
| 589 | } | 572 | } |
| 590 | 573 | ||
| 591 | /** | ||
| 592 | * uwb_bg_joined - is the RC in a beacon group? | ||
| 593 | * @rc: the radio controller | ||
| 594 | * | ||
| 595 | * Returns true if the radio controller is in a beacon group (even if | ||
| 596 | * it's the sole member). | ||
| 597 | */ | ||
| 598 | int uwb_bg_joined(struct uwb_rc *rc) | ||
| 599 | { | ||
| 600 | return rc->beaconing != -1; | ||
| 601 | } | ||
| 602 | EXPORT_SYMBOL_GPL(uwb_bg_joined); | ||
| 603 | |||
| 604 | /* | 574 | /* |
| 605 | * Print beaconing state. | 575 | * Print beaconing state. |
| 606 | */ | 576 | */ |
| @@ -619,9 +589,6 @@ static ssize_t uwb_rc_beacon_show(struct device *dev, | |||
| 619 | 589 | ||
| 620 | /* | 590 | /* |
| 621 | * Start beaconing on the specified channel, or stop beaconing. | 591 | * Start beaconing on the specified channel, or stop beaconing. |
| 622 | * | ||
| 623 | * The BPST offset of when to start searching for a beacon group to | ||
| 624 | * join may be specified. | ||
| 625 | */ | 592 | */ |
| 626 | static ssize_t uwb_rc_beacon_store(struct device *dev, | 593 | static ssize_t uwb_rc_beacon_store(struct device *dev, |
| 627 | struct device_attribute *attr, | 594 | struct device_attribute *attr, |
| @@ -630,12 +597,11 @@ static ssize_t uwb_rc_beacon_store(struct device *dev, | |||
| 630 | struct uwb_dev *uwb_dev = to_uwb_dev(dev); | 597 | struct uwb_dev *uwb_dev = to_uwb_dev(dev); |
| 631 | struct uwb_rc *rc = uwb_dev->rc; | 598 | struct uwb_rc *rc = uwb_dev->rc; |
| 632 | int channel; | 599 | int channel; |
| 633 | unsigned bpst_offset = 0; | ||
| 634 | ssize_t result = -EINVAL; | 600 | ssize_t result = -EINVAL; |
| 635 | 601 | ||
| 636 | result = sscanf(buf, "%d %u\n", &channel, &bpst_offset); | 602 | result = sscanf(buf, "%d", &channel); |
| 637 | if (result >= 1) | 603 | if (result >= 1) |
| 638 | result = uwb_rc_beacon(rc, channel, bpst_offset); | 604 | result = uwb_radio_force_channel(rc, channel); |
| 639 | 605 | ||
| 640 | return result < 0 ? result : size; | 606 | return result < 0 ? result : size; |
| 641 | } | 607 | } |
diff --git a/drivers/uwb/driver.c b/drivers/uwb/driver.c index 521cdeb8497..da77e41de99 100644 --- a/drivers/uwb/driver.c +++ b/drivers/uwb/driver.c | |||
| @@ -53,7 +53,7 @@ | |||
| 53 | #include <linux/err.h> | 53 | #include <linux/err.h> |
| 54 | #include <linux/kdev_t.h> | 54 | #include <linux/kdev_t.h> |
| 55 | #include <linux/random.h> | 55 | #include <linux/random.h> |
| 56 | #include <linux/uwb/debug.h> | 56 | |
| 57 | #include "uwb-internal.h" | 57 | #include "uwb-internal.h" |
| 58 | 58 | ||
| 59 | 59 | ||
| @@ -118,7 +118,6 @@ static int __init uwb_subsys_init(void) | |||
| 118 | result = class_register(&uwb_rc_class); | 118 | result = class_register(&uwb_rc_class); |
| 119 | if (result < 0) | 119 | if (result < 0) |
| 120 | goto error_uwb_rc_class_register; | 120 | goto error_uwb_rc_class_register; |
| 121 | uwbd_start(); | ||
| 122 | uwb_dbg_init(); | 121 | uwb_dbg_init(); |
| 123 | return 0; | 122 | return 0; |
| 124 | 123 | ||
| @@ -132,7 +131,6 @@ module_init(uwb_subsys_init); | |||
| 132 | static void __exit uwb_subsys_exit(void) | 131 | static void __exit uwb_subsys_exit(void) |
| 133 | { | 132 | { |
| 134 | uwb_dbg_exit(); | 133 | uwb_dbg_exit(); |
| 135 | uwbd_stop(); | ||
| 136 | class_unregister(&uwb_rc_class); | 134 | class_unregister(&uwb_rc_class); |
| 137 | uwb_est_destroy(); | 135 | uwb_est_destroy(); |
| 138 | return; | 136 | return; |
diff --git a/drivers/uwb/drp-avail.c b/drivers/uwb/drp-avail.c index 3febd855280..40a540a5a72 100644 --- a/drivers/uwb/drp-avail.c +++ b/drivers/uwb/drp-avail.c | |||
| @@ -58,7 +58,7 @@ void uwb_drp_avail_init(struct uwb_rc *rc) | |||
| 58 | * | 58 | * |
| 59 | * avail = global & local & pending | 59 | * avail = global & local & pending |
| 60 | */ | 60 | */ |
| 61 | static void uwb_drp_available(struct uwb_rc *rc, struct uwb_mas_bm *avail) | 61 | void uwb_drp_available(struct uwb_rc *rc, struct uwb_mas_bm *avail) |
| 62 | { | 62 | { |
| 63 | bitmap_and(avail->bm, rc->drp_avail.global, rc->drp_avail.local, UWB_NUM_MAS); | 63 | bitmap_and(avail->bm, rc->drp_avail.global, rc->drp_avail.local, UWB_NUM_MAS); |
| 64 | bitmap_and(avail->bm, avail->bm, rc->drp_avail.pending, UWB_NUM_MAS); | 64 | bitmap_and(avail->bm, avail->bm, rc->drp_avail.pending, UWB_NUM_MAS); |
| @@ -105,6 +105,7 @@ void uwb_drp_avail_release(struct uwb_rc *rc, struct uwb_mas_bm *mas) | |||
| 105 | bitmap_or(rc->drp_avail.local, rc->drp_avail.local, mas->bm, UWB_NUM_MAS); | 105 | bitmap_or(rc->drp_avail.local, rc->drp_avail.local, mas->bm, UWB_NUM_MAS); |
| 106 | bitmap_or(rc->drp_avail.pending, rc->drp_avail.pending, mas->bm, UWB_NUM_MAS); | 106 | bitmap_or(rc->drp_avail.pending, rc->drp_avail.pending, mas->bm, UWB_NUM_MAS); |
| 107 | rc->drp_avail.ie_valid = false; | 107 | rc->drp_avail.ie_valid = false; |
| 108 | uwb_rsv_handle_drp_avail_change(rc); | ||
| 108 | } | 109 | } |
| 109 | 110 | ||
| 110 | /** | 111 | /** |
| @@ -280,6 +281,7 @@ int uwbd_evt_handle_rc_drp_avail(struct uwb_event *evt) | |||
| 280 | mutex_lock(&rc->rsvs_mutex); | 281 | mutex_lock(&rc->rsvs_mutex); |
| 281 | bitmap_copy(rc->drp_avail.global, bmp, UWB_NUM_MAS); | 282 | bitmap_copy(rc->drp_avail.global, bmp, UWB_NUM_MAS); |
| 282 | rc->drp_avail.ie_valid = false; | 283 | rc->drp_avail.ie_valid = false; |
| 284 | uwb_rsv_handle_drp_avail_change(rc); | ||
| 283 | mutex_unlock(&rc->rsvs_mutex); | 285 | mutex_unlock(&rc->rsvs_mutex); |
| 284 | 286 | ||
| 285 | uwb_rsv_sched_update(rc); | 287 | uwb_rsv_sched_update(rc); |
diff --git a/drivers/uwb/drp-ie.c b/drivers/uwb/drp-ie.c index 882724c5f12..2840d7bf9e6 100644 --- a/drivers/uwb/drp-ie.c +++ b/drivers/uwb/drp-ie.c | |||
| @@ -16,13 +16,102 @@ | |||
| 16 | * You should have received a copy of the GNU General Public License | 16 | * You should have received a copy of the GNU General Public License |
| 17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 18 | */ | 18 | */ |
| 19 | #include <linux/version.h> | ||
| 20 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
| 21 | #include <linux/random.h> | 20 | #include <linux/random.h> |
| 22 | #include <linux/uwb.h> | 21 | #include <linux/uwb.h> |
| 23 | 22 | ||
| 24 | #include "uwb-internal.h" | 23 | #include "uwb-internal.h" |
| 25 | 24 | ||
| 25 | |||
| 26 | /* | ||
| 27 | * Return the reason code for a reservations's DRP IE. | ||
| 28 | */ | ||
| 29 | int uwb_rsv_reason_code(struct uwb_rsv *rsv) | ||
| 30 | { | ||
| 31 | static const int reason_codes[] = { | ||
| 32 | [UWB_RSV_STATE_O_INITIATED] = UWB_DRP_REASON_ACCEPTED, | ||
| 33 | [UWB_RSV_STATE_O_PENDING] = UWB_DRP_REASON_ACCEPTED, | ||
| 34 | [UWB_RSV_STATE_O_MODIFIED] = UWB_DRP_REASON_MODIFIED, | ||
| 35 | [UWB_RSV_STATE_O_ESTABLISHED] = UWB_DRP_REASON_ACCEPTED, | ||
| 36 | [UWB_RSV_STATE_O_TO_BE_MOVED] = UWB_DRP_REASON_ACCEPTED, | ||
| 37 | [UWB_RSV_STATE_O_MOVE_COMBINING] = UWB_DRP_REASON_MODIFIED, | ||
| 38 | [UWB_RSV_STATE_O_MOVE_REDUCING] = UWB_DRP_REASON_MODIFIED, | ||
| 39 | [UWB_RSV_STATE_O_MOVE_EXPANDING] = UWB_DRP_REASON_ACCEPTED, | ||
| 40 | [UWB_RSV_STATE_T_ACCEPTED] = UWB_DRP_REASON_ACCEPTED, | ||
| 41 | [UWB_RSV_STATE_T_CONFLICT] = UWB_DRP_REASON_CONFLICT, | ||
| 42 | [UWB_RSV_STATE_T_PENDING] = UWB_DRP_REASON_PENDING, | ||
| 43 | [UWB_RSV_STATE_T_DENIED] = UWB_DRP_REASON_DENIED, | ||
| 44 | [UWB_RSV_STATE_T_RESIZED] = UWB_DRP_REASON_ACCEPTED, | ||
| 45 | [UWB_RSV_STATE_T_EXPANDING_ACCEPTED] = UWB_DRP_REASON_ACCEPTED, | ||
| 46 | [UWB_RSV_STATE_T_EXPANDING_CONFLICT] = UWB_DRP_REASON_CONFLICT, | ||
| 47 | [UWB_RSV_STATE_T_EXPANDING_PENDING] = UWB_DRP_REASON_PENDING, | ||
| 48 | [UWB_RSV_STATE_T_EXPANDING_DENIED] = UWB_DRP_REASON_DENIED, | ||
| 49 | }; | ||
| 50 | |||
| 51 | return reason_codes[rsv->state]; | ||
| 52 | } | ||
| 53 | |||
| 54 | /* | ||
| 55 | * Return the reason code for a reservations's companion DRP IE . | ||
| 56 | */ | ||
| 57 | int uwb_rsv_companion_reason_code(struct uwb_rsv *rsv) | ||
| 58 | { | ||
| 59 | static const int companion_reason_codes[] = { | ||
| 60 | [UWB_RSV_STATE_O_MOVE_EXPANDING] = UWB_DRP_REASON_ACCEPTED, | ||
| 61 | [UWB_RSV_STATE_T_EXPANDING_ACCEPTED] = UWB_DRP_REASON_ACCEPTED, | ||
| 62 | [UWB_RSV_STATE_T_EXPANDING_CONFLICT] = UWB_DRP_REASON_CONFLICT, | ||
| 63 | [UWB_RSV_STATE_T_EXPANDING_PENDING] = UWB_DRP_REASON_PENDING, | ||
| 64 | [UWB_RSV_STATE_T_EXPANDING_DENIED] = UWB_DRP_REASON_DENIED, | ||
| 65 | }; | ||
| 66 | |||
| 67 | return companion_reason_codes[rsv->state]; | ||
| 68 | } | ||
| 69 | |||
| 70 | /* | ||
| 71 | * Return the status bit for a reservations's DRP IE. | ||
| 72 | */ | ||
| 73 | int uwb_rsv_status(struct uwb_rsv *rsv) | ||
| 74 | { | ||
| 75 | static const int statuses[] = { | ||
| 76 | [UWB_RSV_STATE_O_INITIATED] = 0, | ||
| 77 | [UWB_RSV_STATE_O_PENDING] = 0, | ||
| 78 | [UWB_RSV_STATE_O_MODIFIED] = 1, | ||
| 79 | [UWB_RSV_STATE_O_ESTABLISHED] = 1, | ||
| 80 | [UWB_RSV_STATE_O_TO_BE_MOVED] = 0, | ||
| 81 | [UWB_RSV_STATE_O_MOVE_COMBINING] = 1, | ||
| 82 | [UWB_RSV_STATE_O_MOVE_REDUCING] = 1, | ||
| 83 | [UWB_RSV_STATE_O_MOVE_EXPANDING] = 1, | ||
| 84 | [UWB_RSV_STATE_T_ACCEPTED] = 1, | ||
| 85 | [UWB_RSV_STATE_T_CONFLICT] = 0, | ||
| 86 | [UWB_RSV_STATE_T_PENDING] = 0, | ||
| 87 | [UWB_RSV_STATE_T_DENIED] = 0, | ||
| 88 | [UWB_RSV_STATE_T_RESIZED] = 1, | ||
| 89 | [UWB_RSV_STATE_T_EXPANDING_ACCEPTED] = 1, | ||
| 90 | [UWB_RSV_STATE_T_EXPANDING_CONFLICT] = 1, | ||
| 91 | [UWB_RSV_STATE_T_EXPANDING_PENDING] = 1, | ||
| 92 | [UWB_RSV_STATE_T_EXPANDING_DENIED] = 1, | ||
| 93 | |||
| 94 | }; | ||
| 95 | |||
| 96 | return statuses[rsv->state]; | ||
| 97 | } | ||
| 98 | |||
| 99 | /* | ||
| 100 | * Return the status bit for a reservations's companion DRP IE . | ||
| 101 | */ | ||
| 102 | int uwb_rsv_companion_status(struct uwb_rsv *rsv) | ||
| 103 | { | ||
| 104 | static const int companion_statuses[] = { | ||
| 105 | [UWB_RSV_STATE_O_MOVE_EXPANDING] = 0, | ||
| 106 | [UWB_RSV_STATE_T_EXPANDING_ACCEPTED] = 1, | ||
| 107 | [UWB_RSV_STATE_T_EXPANDING_CONFLICT] = 0, | ||
| 108 | [UWB_RSV_STATE_T_EXPANDING_PENDING] = 0, | ||
| 109 | [UWB_RSV_STATE_T_EXPANDING_DENIED] = 0, | ||
| 110 | }; | ||
| 111 | |||
| 112 | return companion_statuses[rsv->state]; | ||
| 113 | } | ||
| 114 | |||
| 26 | /* | 115 | /* |
| 27 | * Allocate a DRP IE. | 116 | * Allocate a DRP IE. |
| 28 | * | 117 | * |
| @@ -34,16 +123,12 @@ | |||
| 34 | static struct uwb_ie_drp *uwb_drp_ie_alloc(void) | 123 | static struct uwb_ie_drp *uwb_drp_ie_alloc(void) |
| 35 | { | 124 | { |
| 36 | struct uwb_ie_drp *drp_ie; | 125 | struct uwb_ie_drp *drp_ie; |
| 37 | unsigned tiebreaker; | ||
| 38 | 126 | ||
| 39 | drp_ie = kzalloc(sizeof(struct uwb_ie_drp) + | 127 | drp_ie = kzalloc(sizeof(struct uwb_ie_drp) + |
| 40 | UWB_NUM_ZONES * sizeof(struct uwb_drp_alloc), | 128 | UWB_NUM_ZONES * sizeof(struct uwb_drp_alloc), |
| 41 | GFP_KERNEL); | 129 | GFP_KERNEL); |
| 42 | if (drp_ie) { | 130 | if (drp_ie) { |
| 43 | drp_ie->hdr.element_id = UWB_IE_DRP; | 131 | drp_ie->hdr.element_id = UWB_IE_DRP; |
| 44 | |||
| 45 | get_random_bytes(&tiebreaker, sizeof(unsigned)); | ||
| 46 | uwb_ie_drp_set_tiebreaker(drp_ie, tiebreaker & 1); | ||
| 47 | } | 132 | } |
| 48 | return drp_ie; | 133 | return drp_ie; |
| 49 | } | 134 | } |
| @@ -104,43 +189,17 @@ static void uwb_drp_ie_from_bm(struct uwb_ie_drp *drp_ie, | |||
| 104 | */ | 189 | */ |
| 105 | int uwb_drp_ie_update(struct uwb_rsv *rsv) | 190 | int uwb_drp_ie_update(struct uwb_rsv *rsv) |
| 106 | { | 191 | { |
| 107 | struct device *dev = &rsv->rc->uwb_dev.dev; | ||
| 108 | struct uwb_ie_drp *drp_ie; | 192 | struct uwb_ie_drp *drp_ie; |
| 109 | int reason_code, status; | 193 | struct uwb_rsv_move *mv; |
| 194 | int unsafe; | ||
| 110 | 195 | ||
| 111 | switch (rsv->state) { | 196 | if (rsv->state == UWB_RSV_STATE_NONE) { |
| 112 | case UWB_RSV_STATE_NONE: | ||
| 113 | kfree(rsv->drp_ie); | 197 | kfree(rsv->drp_ie); |
| 114 | rsv->drp_ie = NULL; | 198 | rsv->drp_ie = NULL; |
| 115 | return 0; | 199 | return 0; |
| 116 | case UWB_RSV_STATE_O_INITIATED: | ||
| 117 | reason_code = UWB_DRP_REASON_ACCEPTED; | ||
| 118 | status = 0; | ||
| 119 | break; | ||
| 120 | case UWB_RSV_STATE_O_PENDING: | ||
| 121 | reason_code = UWB_DRP_REASON_ACCEPTED; | ||
| 122 | status = 0; | ||
| 123 | break; | ||
| 124 | case UWB_RSV_STATE_O_MODIFIED: | ||
| 125 | reason_code = UWB_DRP_REASON_MODIFIED; | ||
| 126 | status = 1; | ||
| 127 | break; | ||
| 128 | case UWB_RSV_STATE_O_ESTABLISHED: | ||
| 129 | reason_code = UWB_DRP_REASON_ACCEPTED; | ||
| 130 | status = 1; | ||
| 131 | break; | ||
| 132 | case UWB_RSV_STATE_T_ACCEPTED: | ||
| 133 | reason_code = UWB_DRP_REASON_ACCEPTED; | ||
| 134 | status = 1; | ||
| 135 | break; | ||
| 136 | case UWB_RSV_STATE_T_DENIED: | ||
| 137 | reason_code = UWB_DRP_REASON_DENIED; | ||
| 138 | status = 0; | ||
| 139 | break; | ||
| 140 | default: | ||
| 141 | dev_dbg(dev, "rsv with unhandled state (%d)\n", rsv->state); | ||
| 142 | return -EINVAL; | ||
| 143 | } | 200 | } |
| 201 | |||
| 202 | unsafe = rsv->mas.unsafe ? 1 : 0; | ||
| 144 | 203 | ||
| 145 | if (rsv->drp_ie == NULL) { | 204 | if (rsv->drp_ie == NULL) { |
| 146 | rsv->drp_ie = uwb_drp_ie_alloc(); | 205 | rsv->drp_ie = uwb_drp_ie_alloc(); |
| @@ -149,9 +208,11 @@ int uwb_drp_ie_update(struct uwb_rsv *rsv) | |||
| 149 | } | 208 | } |
| 150 | drp_ie = rsv->drp_ie; | 209 | drp_ie = rsv->drp_ie; |
| 151 | 210 | ||
| 211 | uwb_ie_drp_set_unsafe(drp_ie, unsafe); | ||
| 212 | uwb_ie_drp_set_tiebreaker(drp_ie, rsv->tiebreaker); | ||
| 152 | uwb_ie_drp_set_owner(drp_ie, uwb_rsv_is_owner(rsv)); | 213 | uwb_ie_drp_set_owner(drp_ie, uwb_rsv_is_owner(rsv)); |
| 153 | uwb_ie_drp_set_status(drp_ie, status); | 214 | uwb_ie_drp_set_status(drp_ie, uwb_rsv_status(rsv)); |
| 154 | uwb_ie_drp_set_reason_code(drp_ie, reason_code); | 215 | uwb_ie_drp_set_reason_code(drp_ie, uwb_rsv_reason_code(rsv)); |
| 155 | uwb_ie_drp_set_stream_index(drp_ie, rsv->stream); | 216 | uwb_ie_drp_set_stream_index(drp_ie, rsv->stream); |
| 156 | uwb_ie_drp_set_type(drp_ie, rsv->type); | 217 | uwb_ie_drp_set_type(drp_ie, rsv->type); |
| 157 | 218 | ||
| @@ -169,6 +230,27 @@ int uwb_drp_ie_update(struct uwb_rsv *rsv) | |||
| 169 | 230 | ||
| 170 | uwb_drp_ie_from_bm(drp_ie, &rsv->mas); | 231 | uwb_drp_ie_from_bm(drp_ie, &rsv->mas); |
| 171 | 232 | ||
| 233 | if (uwb_rsv_has_two_drp_ies(rsv)) { | ||
| 234 | mv = &rsv->mv; | ||
| 235 | if (mv->companion_drp_ie == NULL) { | ||
| 236 | mv->companion_drp_ie = uwb_drp_ie_alloc(); | ||
| 237 | if (mv->companion_drp_ie == NULL) | ||
| 238 | return -ENOMEM; | ||
| 239 | } | ||
| 240 | drp_ie = mv->companion_drp_ie; | ||
| 241 | |||
| 242 | /* keep all the same configuration of the main drp_ie */ | ||
| 243 | memcpy(drp_ie, rsv->drp_ie, sizeof(struct uwb_ie_drp)); | ||
| 244 | |||
| 245 | |||
| 246 | /* FIXME: handle properly the unsafe bit */ | ||
| 247 | uwb_ie_drp_set_unsafe(drp_ie, 1); | ||
| 248 | uwb_ie_drp_set_status(drp_ie, uwb_rsv_companion_status(rsv)); | ||
| 249 | uwb_ie_drp_set_reason_code(drp_ie, uwb_rsv_companion_reason_code(rsv)); | ||
| 250 | |||
| 251 | uwb_drp_ie_from_bm(drp_ie, &mv->companion_mas); | ||
| 252 | } | ||
| 253 | |||
| 172 | rsv->ie_valid = true; | 254 | rsv->ie_valid = true; |
| 173 | return 0; | 255 | return 0; |
| 174 | } | 256 | } |
| @@ -219,6 +301,8 @@ void uwb_drp_ie_to_bm(struct uwb_mas_bm *bm, const struct uwb_ie_drp *drp_ie) | |||
| 219 | u8 zone; | 301 | u8 zone; |
| 220 | u16 zone_mask; | 302 | u16 zone_mask; |
| 221 | 303 | ||
| 304 | bitmap_zero(bm->bm, UWB_NUM_MAS); | ||
| 305 | |||
| 222 | for (cnt = 0; cnt < numallocs; cnt++) { | 306 | for (cnt = 0; cnt < numallocs; cnt++) { |
| 223 | alloc = &drp_ie->allocs[cnt]; | 307 | alloc = &drp_ie->allocs[cnt]; |
| 224 | zone_bm = le16_to_cpu(alloc->zone_bm); | 308 | zone_bm = le16_to_cpu(alloc->zone_bm); |
| @@ -230,3 +314,4 @@ void uwb_drp_ie_to_bm(struct uwb_mas_bm *bm, const struct uwb_ie_drp *drp_ie) | |||
| 230 | } | 314 | } |
| 231 | } | 315 | } |
| 232 | } | 316 | } |
| 317 | |||
diff --git a/drivers/uwb/drp.c b/drivers/uwb/drp.c index c0b1e5e2bd0..2b4f9406789 100644 --- a/drivers/uwb/drp.c +++ b/drivers/uwb/drp.c | |||
| @@ -23,6 +23,59 @@ | |||
| 23 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
| 24 | #include "uwb-internal.h" | 24 | #include "uwb-internal.h" |
| 25 | 25 | ||
| 26 | |||
| 27 | /* DRP Conflict Actions ([ECMA-368 2nd Edition] 17.4.6) */ | ||
| 28 | enum uwb_drp_conflict_action { | ||
| 29 | /* Reservation is mantained, no action needed */ | ||
| 30 | UWB_DRP_CONFLICT_MANTAIN = 0, | ||
| 31 | |||
| 32 | /* the device shall not transmit frames in conflicting MASs in | ||
| 33 | * the following superframe. If the device is the reservation | ||
| 34 | * target, it shall also set the Reason Code in its DRP IE to | ||
| 35 | * Conflict in its beacon in the following superframe. | ||
| 36 | */ | ||
| 37 | UWB_DRP_CONFLICT_ACT1, | ||
| 38 | |||
| 39 | /* the device shall not set the Reservation Status bit to ONE | ||
| 40 | * and shall not transmit frames in conflicting MASs. If the | ||
| 41 | * device is the reservation target, it shall also set the | ||
| 42 | * Reason Code in its DRP IE to Conflict. | ||
| 43 | */ | ||
| 44 | UWB_DRP_CONFLICT_ACT2, | ||
| 45 | |||
| 46 | /* the device shall not transmit frames in conflicting MASs in | ||
| 47 | * the following superframe. It shall remove the conflicting | ||
| 48 | * MASs from the reservation or set the Reservation Status to | ||
| 49 | * ZERO in its beacon in the following superframe. If the | ||
| 50 | * device is the reservation target, it shall also set the | ||
| 51 | * Reason Code in its DRP IE to Conflict. | ||
| 52 | */ | ||
| 53 | UWB_DRP_CONFLICT_ACT3, | ||
| 54 | }; | ||
| 55 | |||
| 56 | |||
| 57 | static void uwb_rc_set_drp_cmd_done(struct uwb_rc *rc, void *arg, | ||
| 58 | struct uwb_rceb *reply, ssize_t reply_size) | ||
| 59 | { | ||
| 60 | struct uwb_rc_evt_set_drp_ie *r = (struct uwb_rc_evt_set_drp_ie *)reply; | ||
| 61 | |||
| 62 | if (r != NULL) { | ||
| 63 | if (r->bResultCode != UWB_RC_RES_SUCCESS) | ||
| 64 | dev_err(&rc->uwb_dev.dev, "SET-DRP-IE failed: %s (%d)\n", | ||
| 65 | uwb_rc_strerror(r->bResultCode), r->bResultCode); | ||
| 66 | } else | ||
| 67 | dev_err(&rc->uwb_dev.dev, "SET-DRP-IE: timeout\n"); | ||
| 68 | |||
| 69 | spin_lock(&rc->rsvs_lock); | ||
| 70 | if (rc->set_drp_ie_pending > 1) { | ||
| 71 | rc->set_drp_ie_pending = 0; | ||
| 72 | uwb_rsv_queue_update(rc); | ||
| 73 | } else { | ||
| 74 | rc->set_drp_ie_pending = 0; | ||
| 75 | } | ||
| 76 | spin_unlock(&rc->rsvs_lock); | ||
| 77 | } | ||
| 78 | |||
| 26 | /** | 79 | /** |
| 27 | * Construct and send the SET DRP IE | 80 | * Construct and send the SET DRP IE |
| 28 | * | 81 | * |
| @@ -37,28 +90,32 @@ | |||
| 37 | * | 90 | * |
| 38 | * A DRP Availability IE is appended. | 91 | * A DRP Availability IE is appended. |
| 39 | * | 92 | * |
| 40 | * rc->uwb_dev.mutex is held | 93 | * rc->rsvs_mutex is held |
| 41 | * | 94 | * |
| 42 | * FIXME We currently ignore the returned value indicating the remaining space | 95 | * FIXME We currently ignore the returned value indicating the remaining space |
| 43 | * in beacon. This could be used to deny reservation requests earlier if | 96 | * in beacon. This could be used to deny reservation requests earlier if |
| 44 | * determined that they would cause the beacon space to be exceeded. | 97 | * determined that they would cause the beacon space to be exceeded. |
| 45 | */ | 98 | */ |
| 46 | static | 99 | int uwb_rc_send_all_drp_ie(struct uwb_rc *rc) |
| 47 | int uwb_rc_gen_send_drp_ie(struct uwb_rc *rc) | ||
| 48 | { | 100 | { |
| 49 | int result; | 101 | int result; |
| 50 | struct device *dev = &rc->uwb_dev.dev; | ||
| 51 | struct uwb_rc_cmd_set_drp_ie *cmd; | 102 | struct uwb_rc_cmd_set_drp_ie *cmd; |
| 52 | struct uwb_rc_evt_set_drp_ie reply; | ||
| 53 | struct uwb_rsv *rsv; | 103 | struct uwb_rsv *rsv; |
| 104 | struct uwb_rsv_move *mv; | ||
| 54 | int num_bytes = 0; | 105 | int num_bytes = 0; |
| 55 | u8 *IEDataptr; | 106 | u8 *IEDataptr; |
| 56 | 107 | ||
| 57 | result = -ENOMEM; | 108 | result = -ENOMEM; |
| 58 | /* First traverse all reservations to determine memory needed. */ | 109 | /* First traverse all reservations to determine memory needed. */ |
| 59 | list_for_each_entry(rsv, &rc->reservations, rc_node) { | 110 | list_for_each_entry(rsv, &rc->reservations, rc_node) { |
| 60 | if (rsv->drp_ie != NULL) | 111 | if (rsv->drp_ie != NULL) { |
| 61 | num_bytes += rsv->drp_ie->hdr.length + 2; | 112 | num_bytes += rsv->drp_ie->hdr.length + 2; |
| 113 | if (uwb_rsv_has_two_drp_ies(rsv) && | ||
| 114 | (rsv->mv.companion_drp_ie != NULL)) { | ||
| 115 | mv = &rsv->mv; | ||
| 116 | num_bytes += mv->companion_drp_ie->hdr.length + 2; | ||
| 117 | } | ||
| 118 | } | ||
| 62 | } | 119 | } |
| 63 | num_bytes += sizeof(rc->drp_avail.ie); | 120 | num_bytes += sizeof(rc->drp_avail.ie); |
| 64 | cmd = kzalloc(sizeof(*cmd) + num_bytes, GFP_KERNEL); | 121 | cmd = kzalloc(sizeof(*cmd) + num_bytes, GFP_KERNEL); |
| @@ -69,128 +126,322 @@ int uwb_rc_gen_send_drp_ie(struct uwb_rc *rc) | |||
| 69 | cmd->wIELength = num_bytes; | 126 | cmd->wIELength = num_bytes; |
| 70 | IEDataptr = (u8 *)&cmd->IEData[0]; | 127 | IEDataptr = (u8 *)&cmd->IEData[0]; |
| 71 | 128 | ||
| 129 | /* FIXME: DRV avail IE is not always needed */ | ||
| 130 | /* put DRP avail IE first */ | ||
| 131 | memcpy(IEDataptr, &rc->drp_avail.ie, sizeof(rc->drp_avail.ie)); | ||
| 132 | IEDataptr += sizeof(struct uwb_ie_drp_avail); | ||
| 133 | |||
| 72 | /* Next traverse all reservations to place IEs in allocated memory. */ | 134 | /* Next traverse all reservations to place IEs in allocated memory. */ |
| 73 | list_for_each_entry(rsv, &rc->reservations, rc_node) { | 135 | list_for_each_entry(rsv, &rc->reservations, rc_node) { |
| 74 | if (rsv->drp_ie != NULL) { | 136 | if (rsv->drp_ie != NULL) { |
| 75 | memcpy(IEDataptr, rsv->drp_ie, | 137 | memcpy(IEDataptr, rsv->drp_ie, |
| 76 | rsv->drp_ie->hdr.length + 2); | 138 | rsv->drp_ie->hdr.length + 2); |
| 77 | IEDataptr += rsv->drp_ie->hdr.length + 2; | 139 | IEDataptr += rsv->drp_ie->hdr.length + 2; |
| 140 | |||
| 141 | if (uwb_rsv_has_two_drp_ies(rsv) && | ||
| 142 | (rsv->mv.companion_drp_ie != NULL)) { | ||
| 143 | mv = &rsv->mv; | ||
| 144 | memcpy(IEDataptr, mv->companion_drp_ie, | ||
| 145 | mv->companion_drp_ie->hdr.length + 2); | ||
| 146 | IEDataptr += mv->companion_drp_ie->hdr.length + 2; | ||
| 147 | } | ||
| 78 | } | 148 | } |
| 79 | } | 149 | } |
| 80 | memcpy(IEDataptr, &rc->drp_avail.ie, sizeof(rc->drp_avail.ie)); | ||
| 81 | 150 | ||
| 82 | reply.rceb.bEventType = UWB_RC_CET_GENERAL; | 151 | result = uwb_rc_cmd_async(rc, "SET-DRP-IE", &cmd->rccb, sizeof(*cmd) + num_bytes, |
| 83 | reply.rceb.wEvent = UWB_RC_CMD_SET_DRP_IE; | 152 | UWB_RC_CET_GENERAL, UWB_RC_CMD_SET_DRP_IE, |
| 84 | result = uwb_rc_cmd(rc, "SET-DRP-IE", &cmd->rccb, | 153 | uwb_rc_set_drp_cmd_done, NULL); |
| 85 | sizeof(*cmd) + num_bytes, &reply.rceb, | 154 | |
| 86 | sizeof(reply)); | 155 | rc->set_drp_ie_pending = 1; |
| 87 | if (result < 0) | 156 | |
| 88 | goto error_cmd; | ||
| 89 | result = le16_to_cpu(reply.wRemainingSpace); | ||
| 90 | if (reply.bResultCode != UWB_RC_RES_SUCCESS) { | ||
| 91 | dev_err(&rc->uwb_dev.dev, "SET-DRP-IE: command execution " | ||
| 92 | "failed: %s (%d). RemainingSpace in beacon " | ||
| 93 | "= %d\n", uwb_rc_strerror(reply.bResultCode), | ||
| 94 | reply.bResultCode, result); | ||
| 95 | result = -EIO; | ||
| 96 | } else { | ||
| 97 | dev_dbg(dev, "SET-DRP-IE sent. RemainingSpace in beacon " | ||
| 98 | "= %d.\n", result); | ||
| 99 | result = 0; | ||
| 100 | } | ||
| 101 | error_cmd: | ||
| 102 | kfree(cmd); | 157 | kfree(cmd); |
| 103 | error: | 158 | error: |
| 104 | return result; | 159 | return result; |
| 105 | |||
| 106 | } | 160 | } |
| 107 | /** | 161 | |
| 108 | * Send all DRP IEs associated with this host | 162 | /* |
| 109 | * | 163 | * Evaluate the action to perform using conflict resolution rules |
| 110 | * @returns: >= 0 number of bytes still available in the beacon | ||
| 111 | * < 0 errno code on error. | ||
| 112 | * | 164 | * |
| 113 | * As per the protocol we obtain the host controller device lock to access | 165 | * Return a uwb_drp_conflict_action. |
| 114 | * bandwidth structures. | ||
| 115 | */ | 166 | */ |
| 116 | int uwb_rc_send_all_drp_ie(struct uwb_rc *rc) | 167 | static int evaluate_conflict_action(struct uwb_ie_drp *ext_drp_ie, int ext_beacon_slot, |
| 168 | struct uwb_rsv *rsv, int our_status) | ||
| 117 | { | 169 | { |
| 118 | int result; | 170 | int our_tie_breaker = rsv->tiebreaker; |
| 171 | int our_type = rsv->type; | ||
| 172 | int our_beacon_slot = rsv->rc->uwb_dev.beacon_slot; | ||
| 173 | |||
| 174 | int ext_tie_breaker = uwb_ie_drp_tiebreaker(ext_drp_ie); | ||
| 175 | int ext_status = uwb_ie_drp_status(ext_drp_ie); | ||
| 176 | int ext_type = uwb_ie_drp_type(ext_drp_ie); | ||
| 177 | |||
| 178 | |||
| 179 | /* [ECMA-368 2nd Edition] 17.4.6 */ | ||
| 180 | if (ext_type == UWB_DRP_TYPE_PCA && our_type == UWB_DRP_TYPE_PCA) { | ||
| 181 | return UWB_DRP_CONFLICT_MANTAIN; | ||
| 182 | } | ||
| 119 | 183 | ||
| 120 | mutex_lock(&rc->uwb_dev.mutex); | 184 | /* [ECMA-368 2nd Edition] 17.4.6-1 */ |
| 121 | result = uwb_rc_gen_send_drp_ie(rc); | 185 | if (our_type == UWB_DRP_TYPE_ALIEN_BP) { |
| 122 | mutex_unlock(&rc->uwb_dev.mutex); | 186 | return UWB_DRP_CONFLICT_MANTAIN; |
| 123 | return result; | 187 | } |
| 188 | |||
| 189 | /* [ECMA-368 2nd Edition] 17.4.6-2 */ | ||
| 190 | if (ext_type == UWB_DRP_TYPE_ALIEN_BP) { | ||
| 191 | /* here we know our_type != UWB_DRP_TYPE_ALIEN_BP */ | ||
| 192 | return UWB_DRP_CONFLICT_ACT1; | ||
| 193 | } | ||
| 194 | |||
| 195 | /* [ECMA-368 2nd Edition] 17.4.6-3 */ | ||
| 196 | if (our_status == 0 && ext_status == 1) { | ||
| 197 | return UWB_DRP_CONFLICT_ACT2; | ||
| 198 | } | ||
| 199 | |||
| 200 | /* [ECMA-368 2nd Edition] 17.4.6-4 */ | ||
| 201 | if (our_status == 1 && ext_status == 0) { | ||
| 202 | return UWB_DRP_CONFLICT_MANTAIN; | ||
| 203 | } | ||
| 204 | |||
| 205 | /* [ECMA-368 2nd Edition] 17.4.6-5a */ | ||
| 206 | if (our_tie_breaker == ext_tie_breaker && | ||
| 207 | our_beacon_slot < ext_beacon_slot) { | ||
| 208 | return UWB_DRP_CONFLICT_MANTAIN; | ||
| 209 | } | ||
| 210 | |||
| 211 | /* [ECMA-368 2nd Edition] 17.4.6-5b */ | ||
| 212 | if (our_tie_breaker != ext_tie_breaker && | ||
| 213 | our_beacon_slot > ext_beacon_slot) { | ||
| 214 | return UWB_DRP_CONFLICT_MANTAIN; | ||
| 215 | } | ||
| 216 | |||
| 217 | if (our_status == 0) { | ||
| 218 | if (our_tie_breaker == ext_tie_breaker) { | ||
| 219 | /* [ECMA-368 2nd Edition] 17.4.6-6a */ | ||
| 220 | if (our_beacon_slot > ext_beacon_slot) { | ||
| 221 | return UWB_DRP_CONFLICT_ACT2; | ||
| 222 | } | ||
| 223 | } else { | ||
| 224 | /* [ECMA-368 2nd Edition] 17.4.6-6b */ | ||
| 225 | if (our_beacon_slot < ext_beacon_slot) { | ||
| 226 | return UWB_DRP_CONFLICT_ACT2; | ||
| 227 | } | ||
| 228 | } | ||
| 229 | } else { | ||
| 230 | if (our_tie_breaker == ext_tie_breaker) { | ||
| 231 | /* [ECMA-368 2nd Edition] 17.4.6-7a */ | ||
| 232 | if (our_beacon_slot > ext_beacon_slot) { | ||
| 233 | return UWB_DRP_CONFLICT_ACT3; | ||
| 234 | } | ||
| 235 | } else { | ||
| 236 | /* [ECMA-368 2nd Edition] 17.4.6-7b */ | ||
| 237 | if (our_beacon_slot < ext_beacon_slot) { | ||
| 238 | return UWB_DRP_CONFLICT_ACT3; | ||
| 239 | } | ||
| 240 | } | ||
| 241 | } | ||
| 242 | return UWB_DRP_CONFLICT_MANTAIN; | ||
| 124 | } | 243 | } |
| 125 | 244 | ||
| 126 | void uwb_drp_handle_timeout(struct uwb_rsv *rsv) | 245 | static void handle_conflict_normal(struct uwb_ie_drp *drp_ie, |
| 246 | int ext_beacon_slot, | ||
| 247 | struct uwb_rsv *rsv, | ||
| 248 | struct uwb_mas_bm *conflicting_mas) | ||
| 127 | { | 249 | { |
| 128 | struct device *dev = &rsv->rc->uwb_dev.dev; | 250 | struct uwb_rc *rc = rsv->rc; |
| 251 | struct uwb_rsv_move *mv = &rsv->mv; | ||
| 252 | struct uwb_drp_backoff_win *bow = &rc->bow; | ||
| 253 | int action; | ||
| 254 | |||
| 255 | action = evaluate_conflict_action(drp_ie, ext_beacon_slot, rsv, uwb_rsv_status(rsv)); | ||
| 256 | |||
| 257 | if (uwb_rsv_is_owner(rsv)) { | ||
| 258 | switch(action) { | ||
| 259 | case UWB_DRP_CONFLICT_ACT2: | ||
| 260 | /* try move */ | ||
| 261 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_TO_BE_MOVED); | ||
| 262 | if (bow->can_reserve_extra_mases == false) | ||
| 263 | uwb_rsv_backoff_win_increment(rc); | ||
| 264 | |||
| 265 | break; | ||
| 266 | case UWB_DRP_CONFLICT_ACT3: | ||
| 267 | uwb_rsv_backoff_win_increment(rc); | ||
| 268 | /* drop some mases with reason modified */ | ||
| 269 | /* put in the companion the mases to be dropped */ | ||
| 270 | bitmap_and(mv->companion_mas.bm, rsv->mas.bm, conflicting_mas->bm, UWB_NUM_MAS); | ||
| 271 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_MODIFIED); | ||
| 272 | default: | ||
| 273 | break; | ||
| 274 | } | ||
| 275 | } else { | ||
| 276 | switch(action) { | ||
| 277 | case UWB_DRP_CONFLICT_ACT2: | ||
| 278 | case UWB_DRP_CONFLICT_ACT3: | ||
| 279 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_T_CONFLICT); | ||
| 280 | default: | ||
| 281 | break; | ||
| 282 | } | ||
| 129 | 283 | ||
| 130 | dev_dbg(dev, "reservation timeout in state %s (%d)\n", | 284 | } |
| 131 | uwb_rsv_state_str(rsv->state), rsv->state); | 285 | |
| 286 | } | ||
| 132 | 287 | ||
| 133 | switch (rsv->state) { | 288 | static void handle_conflict_expanding(struct uwb_ie_drp *drp_ie, int ext_beacon_slot, |
| 134 | case UWB_RSV_STATE_O_INITIATED: | 289 | struct uwb_rsv *rsv, bool companion_only, |
| 135 | if (rsv->is_multicast) { | 290 | struct uwb_mas_bm *conflicting_mas) |
| 136 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_ESTABLISHED); | 291 | { |
| 137 | return; | 292 | struct uwb_rc *rc = rsv->rc; |
| 293 | struct uwb_drp_backoff_win *bow = &rc->bow; | ||
| 294 | struct uwb_rsv_move *mv = &rsv->mv; | ||
| 295 | int action; | ||
| 296 | |||
| 297 | if (companion_only) { | ||
| 298 | /* status of companion is 0 at this point */ | ||
| 299 | action = evaluate_conflict_action(drp_ie, ext_beacon_slot, rsv, 0); | ||
| 300 | if (uwb_rsv_is_owner(rsv)) { | ||
| 301 | switch(action) { | ||
| 302 | case UWB_DRP_CONFLICT_ACT2: | ||
| 303 | case UWB_DRP_CONFLICT_ACT3: | ||
| 304 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_ESTABLISHED); | ||
| 305 | rsv->needs_release_companion_mas = false; | ||
| 306 | if (bow->can_reserve_extra_mases == false) | ||
| 307 | uwb_rsv_backoff_win_increment(rc); | ||
| 308 | uwb_drp_avail_release(rsv->rc, &rsv->mv.companion_mas); | ||
| 309 | } | ||
| 310 | } else { /* rsv is target */ | ||
| 311 | switch(action) { | ||
| 312 | case UWB_DRP_CONFLICT_ACT2: | ||
| 313 | case UWB_DRP_CONFLICT_ACT3: | ||
| 314 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_T_EXPANDING_CONFLICT); | ||
| 315 | /* send_drp_avail_ie = true; */ | ||
| 316 | } | ||
| 138 | } | 317 | } |
| 139 | break; | 318 | } else { /* also base part of the reservation is conflicting */ |
| 140 | case UWB_RSV_STATE_O_ESTABLISHED: | 319 | if (uwb_rsv_is_owner(rsv)) { |
| 141 | if (rsv->is_multicast) | 320 | uwb_rsv_backoff_win_increment(rc); |
| 142 | return; | 321 | /* remove companion part */ |
| 143 | break; | 322 | uwb_drp_avail_release(rsv->rc, &rsv->mv.companion_mas); |
| 144 | default: | 323 | |
| 145 | break; | 324 | /* drop some mases with reason modified */ |
| 325 | |||
| 326 | /* put in the companion the mases to be dropped */ | ||
| 327 | bitmap_andnot(mv->companion_mas.bm, rsv->mas.bm, conflicting_mas->bm, UWB_NUM_MAS); | ||
| 328 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_MODIFIED); | ||
| 329 | } else { /* it is a target rsv */ | ||
| 330 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_T_CONFLICT); | ||
| 331 | /* send_drp_avail_ie = true; */ | ||
| 332 | } | ||
| 333 | } | ||
| 334 | } | ||
| 335 | |||
| 336 | static void uwb_drp_handle_conflict_rsv(struct uwb_rc *rc, struct uwb_rsv *rsv, | ||
| 337 | struct uwb_rc_evt_drp *drp_evt, | ||
| 338 | struct uwb_ie_drp *drp_ie, | ||
| 339 | struct uwb_mas_bm *conflicting_mas) | ||
| 340 | { | ||
| 341 | struct uwb_rsv_move *mv; | ||
| 342 | |||
| 343 | /* check if the conflicting reservation has two drp_ies */ | ||
| 344 | if (uwb_rsv_has_two_drp_ies(rsv)) { | ||
| 345 | mv = &rsv->mv; | ||
| 346 | if (bitmap_intersects(rsv->mas.bm, conflicting_mas->bm, UWB_NUM_MAS)) { | ||
| 347 | handle_conflict_expanding(drp_ie, drp_evt->beacon_slot_number, | ||
| 348 | rsv, false, conflicting_mas); | ||
| 349 | } else { | ||
| 350 | if (bitmap_intersects(mv->companion_mas.bm, conflicting_mas->bm, UWB_NUM_MAS)) { | ||
| 351 | handle_conflict_expanding(drp_ie, drp_evt->beacon_slot_number, | ||
| 352 | rsv, true, conflicting_mas); | ||
| 353 | } | ||
| 354 | } | ||
| 355 | } else if (bitmap_intersects(rsv->mas.bm, conflicting_mas->bm, UWB_NUM_MAS)) { | ||
| 356 | handle_conflict_normal(drp_ie, drp_evt->beacon_slot_number, rsv, conflicting_mas); | ||
| 146 | } | 357 | } |
| 147 | uwb_rsv_remove(rsv); | ||
| 148 | } | 358 | } |
| 149 | 359 | ||
| 360 | static void uwb_drp_handle_all_conflict_rsv(struct uwb_rc *rc, | ||
| 361 | struct uwb_rc_evt_drp *drp_evt, | ||
| 362 | struct uwb_ie_drp *drp_ie, | ||
| 363 | struct uwb_mas_bm *conflicting_mas) | ||
| 364 | { | ||
| 365 | struct uwb_rsv *rsv; | ||
| 366 | |||
| 367 | list_for_each_entry(rsv, &rc->reservations, rc_node) { | ||
| 368 | uwb_drp_handle_conflict_rsv(rc, rsv, drp_evt, drp_ie, conflicting_mas); | ||
| 369 | } | ||
| 370 | } | ||
| 371 | |||
| 150 | /* | 372 | /* |
| 151 | * Based on the DRP IE, transition a target reservation to a new | 373 | * Based on the DRP IE, transition a target reservation to a new |
| 152 | * state. | 374 | * state. |
| 153 | */ | 375 | */ |
| 154 | static void uwb_drp_process_target(struct uwb_rc *rc, struct uwb_rsv *rsv, | 376 | static void uwb_drp_process_target(struct uwb_rc *rc, struct uwb_rsv *rsv, |
| 155 | struct uwb_ie_drp *drp_ie) | 377 | struct uwb_ie_drp *drp_ie, struct uwb_rc_evt_drp *drp_evt) |
| 156 | { | 378 | { |
| 157 | struct device *dev = &rc->uwb_dev.dev; | 379 | struct device *dev = &rc->uwb_dev.dev; |
| 380 | struct uwb_rsv_move *mv = &rsv->mv; | ||
| 158 | int status; | 381 | int status; |
| 159 | enum uwb_drp_reason reason_code; | 382 | enum uwb_drp_reason reason_code; |
| 160 | 383 | struct uwb_mas_bm mas; | |
| 384 | |||
| 161 | status = uwb_ie_drp_status(drp_ie); | 385 | status = uwb_ie_drp_status(drp_ie); |
| 162 | reason_code = uwb_ie_drp_reason_code(drp_ie); | 386 | reason_code = uwb_ie_drp_reason_code(drp_ie); |
| 387 | uwb_drp_ie_to_bm(&mas, drp_ie); | ||
| 163 | 388 | ||
| 164 | if (status) { | 389 | switch (reason_code) { |
| 165 | switch (reason_code) { | 390 | case UWB_DRP_REASON_ACCEPTED: |
| 166 | case UWB_DRP_REASON_ACCEPTED: | 391 | |
| 167 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_T_ACCEPTED); | 392 | if (rsv->state == UWB_RSV_STATE_T_CONFLICT) { |
| 168 | break; | 393 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_T_CONFLICT); |
| 169 | case UWB_DRP_REASON_MODIFIED: | ||
| 170 | dev_err(dev, "FIXME: unhandled reason code (%d/%d)\n", | ||
| 171 | reason_code, status); | ||
| 172 | break; | 394 | break; |
| 173 | default: | ||
| 174 | dev_warn(dev, "ignoring invalid DRP IE state (%d/%d)\n", | ||
| 175 | reason_code, status); | ||
| 176 | } | 395 | } |
| 177 | } else { | 396 | |
| 178 | switch (reason_code) { | 397 | if (rsv->state == UWB_RSV_STATE_T_EXPANDING_ACCEPTED) { |
| 179 | case UWB_DRP_REASON_ACCEPTED: | 398 | /* drp_ie is companion */ |
| 180 | /* New reservations are handled in uwb_rsv_find(). */ | 399 | if (!bitmap_equal(rsv->mas.bm, mas.bm, UWB_NUM_MAS)) |
| 181 | break; | 400 | /* stroke companion */ |
| 182 | case UWB_DRP_REASON_DENIED: | 401 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_T_EXPANDING_ACCEPTED); |
| 183 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE); | 402 | } else { |
| 184 | break; | 403 | if (!bitmap_equal(rsv->mas.bm, mas.bm, UWB_NUM_MAS)) { |
| 185 | case UWB_DRP_REASON_CONFLICT: | 404 | if (uwb_drp_avail_reserve_pending(rc, &mas) == -EBUSY) { |
| 186 | case UWB_DRP_REASON_MODIFIED: | 405 | /* FIXME: there is a conflict, find |
| 187 | dev_err(dev, "FIXME: unhandled reason code (%d/%d)\n", | 406 | * the conflicting reservations and |
| 188 | reason_code, status); | 407 | * take a sensible action. Consider |
| 408 | * that in drp_ie there is the | ||
| 409 | * "neighbour" */ | ||
| 410 | uwb_drp_handle_all_conflict_rsv(rc, drp_evt, drp_ie, &mas); | ||
| 411 | } else { | ||
| 412 | /* accept the extra reservation */ | ||
| 413 | bitmap_copy(mv->companion_mas.bm, mas.bm, UWB_NUM_MAS); | ||
| 414 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_T_EXPANDING_ACCEPTED); | ||
| 415 | } | ||
| 416 | } else { | ||
| 417 | if (status) { | ||
| 418 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_T_ACCEPTED); | ||
| 419 | } | ||
| 420 | } | ||
| 421 | |||
| 422 | } | ||
| 423 | break; | ||
| 424 | |||
| 425 | case UWB_DRP_REASON_MODIFIED: | ||
| 426 | /* check to see if we have already modified the reservation */ | ||
| 427 | if (bitmap_equal(rsv->mas.bm, mas.bm, UWB_NUM_MAS)) { | ||
| 428 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_T_ACCEPTED); | ||
| 189 | break; | 429 | break; |
| 190 | default: | ||
| 191 | dev_warn(dev, "ignoring invalid DRP IE state (%d/%d)\n", | ||
| 192 | reason_code, status); | ||
| 193 | } | 430 | } |
| 431 | |||
| 432 | /* find if the owner wants to expand or reduce */ | ||
| 433 | if (bitmap_subset(mas.bm, rsv->mas.bm, UWB_NUM_MAS)) { | ||
| 434 | /* owner is reducing */ | ||
| 435 | bitmap_andnot(mv->companion_mas.bm, rsv->mas.bm, mas.bm, UWB_NUM_MAS); | ||
| 436 | uwb_drp_avail_release(rsv->rc, &mv->companion_mas); | ||
| 437 | } | ||
| 438 | |||
| 439 | bitmap_copy(rsv->mas.bm, mas.bm, UWB_NUM_MAS); | ||
| 440 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_T_RESIZED); | ||
| 441 | break; | ||
| 442 | default: | ||
| 443 | dev_warn(dev, "ignoring invalid DRP IE state (%d/%d)\n", | ||
| 444 | reason_code, status); | ||
| 194 | } | 445 | } |
| 195 | } | 446 | } |
| 196 | 447 | ||
| @@ -199,23 +450,60 @@ static void uwb_drp_process_target(struct uwb_rc *rc, struct uwb_rsv *rsv, | |||
| 199 | * state. | 450 | * state. |
| 200 | */ | 451 | */ |
| 201 | static void uwb_drp_process_owner(struct uwb_rc *rc, struct uwb_rsv *rsv, | 452 | static void uwb_drp_process_owner(struct uwb_rc *rc, struct uwb_rsv *rsv, |
| 202 | struct uwb_ie_drp *drp_ie) | 453 | struct uwb_dev *src, struct uwb_ie_drp *drp_ie, |
| 454 | struct uwb_rc_evt_drp *drp_evt) | ||
| 203 | { | 455 | { |
| 204 | struct device *dev = &rc->uwb_dev.dev; | 456 | struct device *dev = &rc->uwb_dev.dev; |
| 457 | struct uwb_rsv_move *mv = &rsv->mv; | ||
| 205 | int status; | 458 | int status; |
| 206 | enum uwb_drp_reason reason_code; | 459 | enum uwb_drp_reason reason_code; |
| 460 | struct uwb_mas_bm mas; | ||
| 207 | 461 | ||
| 208 | status = uwb_ie_drp_status(drp_ie); | 462 | status = uwb_ie_drp_status(drp_ie); |
| 209 | reason_code = uwb_ie_drp_reason_code(drp_ie); | 463 | reason_code = uwb_ie_drp_reason_code(drp_ie); |
| 464 | uwb_drp_ie_to_bm(&mas, drp_ie); | ||
| 210 | 465 | ||
| 211 | if (status) { | 466 | if (status) { |
| 212 | switch (reason_code) { | 467 | switch (reason_code) { |
| 213 | case UWB_DRP_REASON_ACCEPTED: | 468 | case UWB_DRP_REASON_ACCEPTED: |
| 214 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_ESTABLISHED); | 469 | switch (rsv->state) { |
| 215 | break; | 470 | case UWB_RSV_STATE_O_PENDING: |
| 216 | case UWB_DRP_REASON_MODIFIED: | 471 | case UWB_RSV_STATE_O_INITIATED: |
| 217 | dev_err(dev, "FIXME: unhandled reason code (%d/%d)\n", | 472 | case UWB_RSV_STATE_O_ESTABLISHED: |
| 218 | reason_code, status); | 473 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_ESTABLISHED); |
| 474 | break; | ||
| 475 | case UWB_RSV_STATE_O_MODIFIED: | ||
| 476 | if (bitmap_equal(mas.bm, rsv->mas.bm, UWB_NUM_MAS)) { | ||
| 477 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_ESTABLISHED); | ||
| 478 | } else { | ||
| 479 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_MODIFIED); | ||
| 480 | } | ||
| 481 | break; | ||
| 482 | |||
| 483 | case UWB_RSV_STATE_O_MOVE_REDUCING: /* shouldn' t be a problem */ | ||
| 484 | if (bitmap_equal(mas.bm, rsv->mas.bm, UWB_NUM_MAS)) { | ||
| 485 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_ESTABLISHED); | ||
| 486 | } else { | ||
| 487 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_MOVE_REDUCING); | ||
| 488 | } | ||
| 489 | break; | ||
| 490 | case UWB_RSV_STATE_O_MOVE_EXPANDING: | ||
| 491 | if (bitmap_equal(mas.bm, mv->companion_mas.bm, UWB_NUM_MAS)) { | ||
| 492 | /* Companion reservation accepted */ | ||
| 493 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_MOVE_COMBINING); | ||
| 494 | } else { | ||
| 495 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_MOVE_EXPANDING); | ||
| 496 | } | ||
| 497 | break; | ||
| 498 | case UWB_RSV_STATE_O_MOVE_COMBINING: | ||
| 499 | if (bitmap_equal(mas.bm, rsv->mas.bm, UWB_NUM_MAS)) | ||
| 500 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_MOVE_REDUCING); | ||
| 501 | else | ||
| 502 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_MOVE_COMBINING); | ||
| 503 | break; | ||
| 504 | default: | ||
| 505 | break; | ||
| 506 | } | ||
| 219 | break; | 507 | break; |
| 220 | default: | 508 | default: |
| 221 | dev_warn(dev, "ignoring invalid DRP IE state (%d/%d)\n", | 509 | dev_warn(dev, "ignoring invalid DRP IE state (%d/%d)\n", |
| @@ -230,9 +518,10 @@ static void uwb_drp_process_owner(struct uwb_rc *rc, struct uwb_rsv *rsv, | |||
| 230 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE); | 518 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE); |
| 231 | break; | 519 | break; |
| 232 | case UWB_DRP_REASON_CONFLICT: | 520 | case UWB_DRP_REASON_CONFLICT: |
| 233 | case UWB_DRP_REASON_MODIFIED: | 521 | /* resolve the conflict */ |
| 234 | dev_err(dev, "FIXME: unhandled reason code (%d/%d)\n", | 522 | bitmap_complement(mas.bm, src->last_availability_bm, |
| 235 | reason_code, status); | 523 | UWB_NUM_MAS); |
| 524 | uwb_drp_handle_conflict_rsv(rc, rsv, drp_evt, drp_ie, &mas); | ||
| 236 | break; | 525 | break; |
| 237 | default: | 526 | default: |
| 238 | dev_warn(dev, "ignoring invalid DRP IE state (%d/%d)\n", | 527 | dev_warn(dev, "ignoring invalid DRP IE state (%d/%d)\n", |
| @@ -241,12 +530,110 @@ static void uwb_drp_process_owner(struct uwb_rc *rc, struct uwb_rsv *rsv, | |||
| 241 | } | 530 | } |
| 242 | } | 531 | } |
| 243 | 532 | ||
| 533 | static void uwb_cnflt_alien_stroke_timer(struct uwb_cnflt_alien *cnflt) | ||
| 534 | { | ||
| 535 | unsigned timeout_us = UWB_MAX_LOST_BEACONS * UWB_SUPERFRAME_LENGTH_US; | ||
| 536 | mod_timer(&cnflt->timer, jiffies + usecs_to_jiffies(timeout_us)); | ||
| 537 | } | ||
| 538 | |||
| 539 | static void uwb_cnflt_update_work(struct work_struct *work) | ||
| 540 | { | ||
| 541 | struct uwb_cnflt_alien *cnflt = container_of(work, | ||
| 542 | struct uwb_cnflt_alien, | ||
| 543 | cnflt_update_work); | ||
| 544 | struct uwb_cnflt_alien *c; | ||
| 545 | struct uwb_rc *rc = cnflt->rc; | ||
| 546 | |||
| 547 | unsigned long delay_us = UWB_MAS_LENGTH_US * UWB_MAS_PER_ZONE; | ||
| 548 | |||
| 549 | mutex_lock(&rc->rsvs_mutex); | ||
| 550 | |||
| 551 | list_del(&cnflt->rc_node); | ||
| 552 | |||
| 553 | /* update rc global conflicting alien bitmap */ | ||
| 554 | bitmap_zero(rc->cnflt_alien_bitmap.bm, UWB_NUM_MAS); | ||
| 555 | |||
| 556 | list_for_each_entry(c, &rc->cnflt_alien_list, rc_node) { | ||
| 557 | bitmap_or(rc->cnflt_alien_bitmap.bm, rc->cnflt_alien_bitmap.bm, c->mas.bm, UWB_NUM_MAS); | ||
| 558 | } | ||
| 559 | |||
| 560 | queue_delayed_work(rc->rsv_workq, &rc->rsv_alien_bp_work, usecs_to_jiffies(delay_us)); | ||
| 561 | |||
| 562 | kfree(cnflt); | ||
| 563 | mutex_unlock(&rc->rsvs_mutex); | ||
| 564 | } | ||
| 565 | |||
| 566 | static void uwb_cnflt_timer(unsigned long arg) | ||
| 567 | { | ||
| 568 | struct uwb_cnflt_alien *cnflt = (struct uwb_cnflt_alien *)arg; | ||
| 569 | |||
| 570 | queue_work(cnflt->rc->rsv_workq, &cnflt->cnflt_update_work); | ||
| 571 | } | ||
| 572 | |||
| 244 | /* | 573 | /* |
| 245 | * Process a received DRP IE, it's either for a reservation owned by | 574 | * We have received an DRP_IE of type Alien BP and we need to make |
| 246 | * the RC or targeted at it (or it's for a WUSB cluster reservation). | 575 | * sure we do not transmit in conflicting MASs. |
| 247 | */ | 576 | */ |
| 248 | static void uwb_drp_process(struct uwb_rc *rc, struct uwb_dev *src, | 577 | static void uwb_drp_handle_alien_drp(struct uwb_rc *rc, struct uwb_ie_drp *drp_ie) |
| 249 | struct uwb_ie_drp *drp_ie) | 578 | { |
| 579 | struct device *dev = &rc->uwb_dev.dev; | ||
| 580 | struct uwb_mas_bm mas; | ||
| 581 | struct uwb_cnflt_alien *cnflt; | ||
| 582 | char buf[72]; | ||
| 583 | unsigned long delay_us = UWB_MAS_LENGTH_US * UWB_MAS_PER_ZONE; | ||
| 584 | |||
| 585 | uwb_drp_ie_to_bm(&mas, drp_ie); | ||
| 586 | bitmap_scnprintf(buf, sizeof(buf), mas.bm, UWB_NUM_MAS); | ||
| 587 | |||
| 588 | list_for_each_entry(cnflt, &rc->cnflt_alien_list, rc_node) { | ||
| 589 | if (bitmap_equal(cnflt->mas.bm, mas.bm, UWB_NUM_MAS)) { | ||
| 590 | /* Existing alien BP reservation conflicting | ||
| 591 | * bitmap, just reset the timer */ | ||
| 592 | uwb_cnflt_alien_stroke_timer(cnflt); | ||
| 593 | return; | ||
| 594 | } | ||
| 595 | } | ||
| 596 | |||
| 597 | /* New alien BP reservation conflicting bitmap */ | ||
| 598 | |||
| 599 | /* alloc and initialize new uwb_cnflt_alien */ | ||
| 600 | cnflt = kzalloc(sizeof(struct uwb_cnflt_alien), GFP_KERNEL); | ||
| 601 | if (!cnflt) | ||
| 602 | dev_err(dev, "failed to alloc uwb_cnflt_alien struct\n"); | ||
| 603 | INIT_LIST_HEAD(&cnflt->rc_node); | ||
| 604 | init_timer(&cnflt->timer); | ||
| 605 | cnflt->timer.function = uwb_cnflt_timer; | ||
| 606 | cnflt->timer.data = (unsigned long)cnflt; | ||
| 607 | |||
| 608 | cnflt->rc = rc; | ||
| 609 | INIT_WORK(&cnflt->cnflt_update_work, uwb_cnflt_update_work); | ||
| 610 | |||
| 611 | bitmap_copy(cnflt->mas.bm, mas.bm, UWB_NUM_MAS); | ||
| 612 | |||
| 613 | list_add_tail(&cnflt->rc_node, &rc->cnflt_alien_list); | ||
| 614 | |||
| 615 | /* update rc global conflicting alien bitmap */ | ||
| 616 | bitmap_or(rc->cnflt_alien_bitmap.bm, rc->cnflt_alien_bitmap.bm, mas.bm, UWB_NUM_MAS); | ||
| 617 | |||
| 618 | queue_delayed_work(rc->rsv_workq, &rc->rsv_alien_bp_work, usecs_to_jiffies(delay_us)); | ||
| 619 | |||
| 620 | /* start the timer */ | ||
| 621 | uwb_cnflt_alien_stroke_timer(cnflt); | ||
| 622 | } | ||
| 623 | |||
| 624 | static void uwb_drp_process_not_involved(struct uwb_rc *rc, | ||
| 625 | struct uwb_rc_evt_drp *drp_evt, | ||
| 626 | struct uwb_ie_drp *drp_ie) | ||
| 627 | { | ||
| 628 | struct uwb_mas_bm mas; | ||
| 629 | |||
| 630 | uwb_drp_ie_to_bm(&mas, drp_ie); | ||
| 631 | uwb_drp_handle_all_conflict_rsv(rc, drp_evt, drp_ie, &mas); | ||
| 632 | } | ||
| 633 | |||
| 634 | static void uwb_drp_process_involved(struct uwb_rc *rc, struct uwb_dev *src, | ||
| 635 | struct uwb_rc_evt_drp *drp_evt, | ||
| 636 | struct uwb_ie_drp *drp_ie) | ||
| 250 | { | 637 | { |
| 251 | struct uwb_rsv *rsv; | 638 | struct uwb_rsv *rsv; |
| 252 | 639 | ||
| @@ -259,7 +646,7 @@ static void uwb_drp_process(struct uwb_rc *rc, struct uwb_dev *src, | |||
| 259 | */ | 646 | */ |
| 260 | return; | 647 | return; |
| 261 | } | 648 | } |
| 262 | 649 | ||
| 263 | /* | 650 | /* |
| 264 | * Do nothing with DRP IEs for reservations that have been | 651 | * Do nothing with DRP IEs for reservations that have been |
| 265 | * terminated. | 652 | * terminated. |
| @@ -268,13 +655,43 @@ static void uwb_drp_process(struct uwb_rc *rc, struct uwb_dev *src, | |||
| 268 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE); | 655 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE); |
| 269 | return; | 656 | return; |
| 270 | } | 657 | } |
| 271 | 658 | ||
| 272 | if (uwb_ie_drp_owner(drp_ie)) | 659 | if (uwb_ie_drp_owner(drp_ie)) |
| 273 | uwb_drp_process_target(rc, rsv, drp_ie); | 660 | uwb_drp_process_target(rc, rsv, drp_ie, drp_evt); |
| 661 | else | ||
| 662 | uwb_drp_process_owner(rc, rsv, src, drp_ie, drp_evt); | ||
| 663 | |||
| 664 | } | ||
| 665 | |||
| 666 | |||
| 667 | static bool uwb_drp_involves_us(struct uwb_rc *rc, struct uwb_ie_drp *drp_ie) | ||
| 668 | { | ||
| 669 | return uwb_dev_addr_cmp(&rc->uwb_dev.dev_addr, &drp_ie->dev_addr) == 0; | ||
| 670 | } | ||
| 671 | |||
| 672 | /* | ||
| 673 | * Process a received DRP IE. | ||
| 674 | */ | ||
| 675 | static void uwb_drp_process(struct uwb_rc *rc, struct uwb_rc_evt_drp *drp_evt, | ||
| 676 | struct uwb_dev *src, struct uwb_ie_drp *drp_ie) | ||
| 677 | { | ||
| 678 | if (uwb_ie_drp_type(drp_ie) == UWB_DRP_TYPE_ALIEN_BP) | ||
| 679 | uwb_drp_handle_alien_drp(rc, drp_ie); | ||
| 680 | else if (uwb_drp_involves_us(rc, drp_ie)) | ||
| 681 | uwb_drp_process_involved(rc, src, drp_evt, drp_ie); | ||
| 274 | else | 682 | else |
| 275 | uwb_drp_process_owner(rc, rsv, drp_ie); | 683 | uwb_drp_process_not_involved(rc, drp_evt, drp_ie); |
| 276 | } | 684 | } |
| 277 | 685 | ||
| 686 | /* | ||
| 687 | * Process a received DRP Availability IE | ||
| 688 | */ | ||
| 689 | static void uwb_drp_availability_process(struct uwb_rc *rc, struct uwb_dev *src, | ||
| 690 | struct uwb_ie_drp_avail *drp_availability_ie) | ||
| 691 | { | ||
| 692 | bitmap_copy(src->last_availability_bm, | ||
| 693 | drp_availability_ie->bmp, UWB_NUM_MAS); | ||
| 694 | } | ||
| 278 | 695 | ||
| 279 | /* | 696 | /* |
| 280 | * Process all the DRP IEs (both DRP IEs and the DRP Availability IE) | 697 | * Process all the DRP IEs (both DRP IEs and the DRP Availability IE) |
| @@ -296,10 +713,10 @@ void uwb_drp_process_all(struct uwb_rc *rc, struct uwb_rc_evt_drp *drp_evt, | |||
| 296 | 713 | ||
| 297 | switch (ie_hdr->element_id) { | 714 | switch (ie_hdr->element_id) { |
| 298 | case UWB_IE_DRP_AVAILABILITY: | 715 | case UWB_IE_DRP_AVAILABILITY: |
| 299 | /* FIXME: does something need to be done with this? */ | 716 | uwb_drp_availability_process(rc, src_dev, (struct uwb_ie_drp_avail *)ie_hdr); |
| 300 | break; | 717 | break; |
| 301 | case UWB_IE_DRP: | 718 | case UWB_IE_DRP: |
| 302 | uwb_drp_process(rc, src_dev, (struct uwb_ie_drp *)ie_hdr); | 719 | uwb_drp_process(rc, drp_evt, src_dev, (struct uwb_ie_drp *)ie_hdr); |
| 303 | break; | 720 | break; |
| 304 | default: | 721 | default: |
| 305 | dev_warn(dev, "unexpected IE in DRP notification\n"); | 722 | dev_warn(dev, "unexpected IE in DRP notification\n"); |
| @@ -312,55 +729,6 @@ void uwb_drp_process_all(struct uwb_rc *rc, struct uwb_rc_evt_drp *drp_evt, | |||
| 312 | (int)ielen); | 729 | (int)ielen); |
| 313 | } | 730 | } |
| 314 | 731 | ||
| 315 | |||
| 316 | /* | ||
| 317 | * Go through all the DRP IEs and find the ones that conflict with our | ||
| 318 | * reservations. | ||
| 319 | * | ||
| 320 | * FIXME: must resolve the conflict according the the rules in | ||
| 321 | * [ECMA-368]. | ||
| 322 | */ | ||
| 323 | static | ||
| 324 | void uwb_drp_process_conflict_all(struct uwb_rc *rc, struct uwb_rc_evt_drp *drp_evt, | ||
| 325 | size_t ielen, struct uwb_dev *src_dev) | ||
| 326 | { | ||
| 327 | struct device *dev = &rc->uwb_dev.dev; | ||
| 328 | struct uwb_ie_hdr *ie_hdr; | ||
| 329 | struct uwb_ie_drp *drp_ie; | ||
| 330 | void *ptr; | ||
| 331 | |||
| 332 | ptr = drp_evt->ie_data; | ||
| 333 | for (;;) { | ||
| 334 | ie_hdr = uwb_ie_next(&ptr, &ielen); | ||
| 335 | if (!ie_hdr) | ||
| 336 | break; | ||
| 337 | |||
| 338 | drp_ie = container_of(ie_hdr, struct uwb_ie_drp, hdr); | ||
| 339 | |||
| 340 | /* FIXME: check if this DRP IE conflicts. */ | ||
| 341 | } | ||
| 342 | |||
| 343 | if (ielen > 0) | ||
| 344 | dev_warn(dev, "%d octets remaining in DRP notification\n", | ||
| 345 | (int)ielen); | ||
| 346 | } | ||
| 347 | |||
| 348 | |||
| 349 | /* | ||
| 350 | * Terminate all reservations owned by, or targeted at, 'uwb_dev'. | ||
| 351 | */ | ||
| 352 | static void uwb_drp_terminate_all(struct uwb_rc *rc, struct uwb_dev *uwb_dev) | ||
| 353 | { | ||
| 354 | struct uwb_rsv *rsv; | ||
| 355 | |||
| 356 | list_for_each_entry(rsv, &rc->reservations, rc_node) { | ||
| 357 | if (rsv->owner == uwb_dev | ||
| 358 | || (rsv->target.type == UWB_RSV_TARGET_DEV && rsv->target.dev == uwb_dev)) | ||
| 359 | uwb_rsv_remove(rsv); | ||
| 360 | } | ||
| 361 | } | ||
| 362 | |||
| 363 | |||
| 364 | /** | 732 | /** |
| 365 | * uwbd_evt_handle_rc_drp - handle a DRP_IE event | 733 | * uwbd_evt_handle_rc_drp - handle a DRP_IE event |
| 366 | * @evt: the DRP_IE event from the radio controller | 734 | * @evt: the DRP_IE event from the radio controller |
| @@ -401,7 +769,6 @@ int uwbd_evt_handle_rc_drp(struct uwb_event *evt) | |||
| 401 | size_t ielength, bytes_left; | 769 | size_t ielength, bytes_left; |
| 402 | struct uwb_dev_addr src_addr; | 770 | struct uwb_dev_addr src_addr; |
| 403 | struct uwb_dev *src_dev; | 771 | struct uwb_dev *src_dev; |
| 404 | int reason; | ||
| 405 | 772 | ||
| 406 | /* Is there enough data to decode the event (and any IEs in | 773 | /* Is there enough data to decode the event (and any IEs in |
| 407 | its payload)? */ | 774 | its payload)? */ |
| @@ -437,22 +804,8 @@ int uwbd_evt_handle_rc_drp(struct uwb_event *evt) | |||
| 437 | 804 | ||
| 438 | mutex_lock(&rc->rsvs_mutex); | 805 | mutex_lock(&rc->rsvs_mutex); |
| 439 | 806 | ||
| 440 | reason = uwb_rc_evt_drp_reason(drp_evt); | 807 | /* We do not distinguish from the reason */ |
| 441 | 808 | uwb_drp_process_all(rc, drp_evt, ielength, src_dev); | |
| 442 | switch (reason) { | ||
| 443 | case UWB_DRP_NOTIF_DRP_IE_RCVD: | ||
| 444 | uwb_drp_process_all(rc, drp_evt, ielength, src_dev); | ||
| 445 | break; | ||
| 446 | case UWB_DRP_NOTIF_CONFLICT: | ||
| 447 | uwb_drp_process_conflict_all(rc, drp_evt, ielength, src_dev); | ||
| 448 | break; | ||
| 449 | case UWB_DRP_NOTIF_TERMINATE: | ||
| 450 | uwb_drp_terminate_all(rc, src_dev); | ||
| 451 | break; | ||
| 452 | default: | ||
| 453 | dev_warn(dev, "ignored DRP event with reason code: %d\n", reason); | ||
| 454 | break; | ||
| 455 | } | ||
| 456 | 809 | ||
| 457 | mutex_unlock(&rc->rsvs_mutex); | 810 | mutex_unlock(&rc->rsvs_mutex); |
| 458 | 811 | ||
diff --git a/drivers/uwb/est.c b/drivers/uwb/est.c index 5fe566b7c84..328fcc2b609 100644 --- a/drivers/uwb/est.c +++ b/drivers/uwb/est.c | |||
| @@ -40,10 +40,8 @@ | |||
| 40 | * uwb_est_get_size() | 40 | * uwb_est_get_size() |
| 41 | */ | 41 | */ |
| 42 | #include <linux/spinlock.h> | 42 | #include <linux/spinlock.h> |
| 43 | #define D_LOCAL 0 | ||
| 44 | #include <linux/uwb/debug.h> | ||
| 45 | #include "uwb-internal.h" | ||
| 46 | 43 | ||
| 44 | #include "uwb-internal.h" | ||
| 47 | 45 | ||
| 48 | struct uwb_est { | 46 | struct uwb_est { |
| 49 | u16 type_event_high; | 47 | u16 type_event_high; |
| @@ -52,7 +50,6 @@ struct uwb_est { | |||
| 52 | const struct uwb_est_entry *entry; | 50 | const struct uwb_est_entry *entry; |
| 53 | }; | 51 | }; |
| 54 | 52 | ||
| 55 | |||
| 56 | static struct uwb_est *uwb_est; | 53 | static struct uwb_est *uwb_est; |
| 57 | static u8 uwb_est_size; | 54 | static u8 uwb_est_size; |
| 58 | static u8 uwb_est_used; | 55 | static u8 uwb_est_used; |
| @@ -440,21 +437,12 @@ ssize_t uwb_est_find_size(struct uwb_rc *rc, const struct uwb_rceb *rceb, | |||
| 440 | u8 *ptr = (u8 *) rceb; | 437 | u8 *ptr = (u8 *) rceb; |
| 441 | 438 | ||
| 442 | read_lock_irqsave(&uwb_est_lock, flags); | 439 | read_lock_irqsave(&uwb_est_lock, flags); |
| 443 | d_printf(2, dev, "Size query for event 0x%02x/%04x/%02x," | ||
| 444 | " buffer size %ld\n", | ||
| 445 | (unsigned) rceb->bEventType, | ||
| 446 | (unsigned) le16_to_cpu(rceb->wEvent), | ||
| 447 | (unsigned) rceb->bEventContext, | ||
| 448 | (long) rceb_size); | ||
| 449 | size = -ENOSPC; | 440 | size = -ENOSPC; |
| 450 | if (rceb_size < sizeof(*rceb)) | 441 | if (rceb_size < sizeof(*rceb)) |
| 451 | goto out; | 442 | goto out; |
| 452 | event = le16_to_cpu(rceb->wEvent); | 443 | event = le16_to_cpu(rceb->wEvent); |
| 453 | type_event_high = rceb->bEventType << 8 | (event & 0xff00) >> 8; | 444 | type_event_high = rceb->bEventType << 8 | (event & 0xff00) >> 8; |
| 454 | for (itr = 0; itr < uwb_est_used; itr++) { | 445 | for (itr = 0; itr < uwb_est_used; itr++) { |
| 455 | d_printf(3, dev, "Checking EST 0x%04x/%04x/%04x\n", | ||
| 456 | uwb_est[itr].type_event_high, uwb_est[itr].vendor, | ||
| 457 | uwb_est[itr].product); | ||
| 458 | if (uwb_est[itr].type_event_high != type_event_high) | 446 | if (uwb_est[itr].type_event_high != type_event_high) |
| 459 | continue; | 447 | continue; |
| 460 | size = uwb_est_get_size(rc, &uwb_est[itr], | 448 | size = uwb_est_get_size(rc, &uwb_est[itr], |
diff --git a/drivers/uwb/hwa-rc.c b/drivers/uwb/hwa-rc.c index 3d26fa0f8ae..559f8784acf 100644 --- a/drivers/uwb/hwa-rc.c +++ b/drivers/uwb/hwa-rc.c | |||
| @@ -51,16 +51,14 @@ | |||
| 51 | * | 51 | * |
| 52 | * | 52 | * |
| 53 | */ | 53 | */ |
| 54 | #include <linux/version.h> | ||
| 55 | #include <linux/init.h> | 54 | #include <linux/init.h> |
| 56 | #include <linux/module.h> | 55 | #include <linux/module.h> |
| 57 | #include <linux/usb.h> | 56 | #include <linux/usb.h> |
| 58 | #include <linux/usb/wusb.h> | 57 | #include <linux/usb/wusb.h> |
| 59 | #include <linux/usb/wusb-wa.h> | 58 | #include <linux/usb/wusb-wa.h> |
| 60 | #include <linux/uwb.h> | 59 | #include <linux/uwb.h> |
| 60 | |||
| 61 | #include "uwb-internal.h" | 61 | #include "uwb-internal.h" |
| 62 | #define D_LOCAL 1 | ||
| 63 | #include <linux/uwb/debug.h> | ||
| 64 | 62 | ||
| 65 | /* The device uses commands and events from the WHCI specification, although | 63 | /* The device uses commands and events from the WHCI specification, although |
| 66 | * reporting itself as WUSB compliant. */ | 64 | * reporting itself as WUSB compliant. */ |
| @@ -631,17 +629,13 @@ void hwarc_neep_cb(struct urb *urb) | |||
| 631 | 629 | ||
| 632 | switch (result = urb->status) { | 630 | switch (result = urb->status) { |
| 633 | case 0: | 631 | case 0: |
| 634 | d_printf(3, dev, "NEEP: receive stat %d, %zu bytes\n", | ||
| 635 | urb->status, (size_t)urb->actual_length); | ||
| 636 | uwb_rc_neh_grok(hwarc->uwb_rc, urb->transfer_buffer, | 632 | uwb_rc_neh_grok(hwarc->uwb_rc, urb->transfer_buffer, |
| 637 | urb->actual_length); | 633 | urb->actual_length); |
| 638 | break; | 634 | break; |
| 639 | case -ECONNRESET: /* Not an error, but a controlled situation; */ | 635 | case -ECONNRESET: /* Not an error, but a controlled situation; */ |
| 640 | case -ENOENT: /* (we killed the URB)...so, no broadcast */ | 636 | case -ENOENT: /* (we killed the URB)...so, no broadcast */ |
| 641 | d_printf(2, dev, "NEEP: URB reset/noent %d\n", urb->status); | ||
| 642 | goto out; | 637 | goto out; |
| 643 | case -ESHUTDOWN: /* going away! */ | 638 | case -ESHUTDOWN: /* going away! */ |
| 644 | d_printf(2, dev, "NEEP: URB down %d\n", urb->status); | ||
| 645 | goto out; | 639 | goto out; |
| 646 | default: /* On general errors, retry unless it gets ugly */ | 640 | default: /* On general errors, retry unless it gets ugly */ |
| 647 | if (edc_inc(&hwarc->neep_edc, EDC_MAX_ERRORS, | 641 | if (edc_inc(&hwarc->neep_edc, EDC_MAX_ERRORS, |
| @@ -650,7 +644,6 @@ void hwarc_neep_cb(struct urb *urb) | |||
| 650 | dev_err(dev, "NEEP: URB error %d\n", urb->status); | 644 | dev_err(dev, "NEEP: URB error %d\n", urb->status); |
| 651 | } | 645 | } |
| 652 | result = usb_submit_urb(urb, GFP_ATOMIC); | 646 | result = usb_submit_urb(urb, GFP_ATOMIC); |
| 653 | d_printf(3, dev, "NEEP: submit %d\n", result); | ||
| 654 | if (result < 0) { | 647 | if (result < 0) { |
| 655 | dev_err(dev, "NEEP: Can't resubmit URB (%d) resetting device\n", | 648 | dev_err(dev, "NEEP: Can't resubmit URB (%d) resetting device\n", |
| 656 | result); | 649 | result); |
| @@ -759,11 +752,11 @@ static int hwarc_get_version(struct uwb_rc *rc) | |||
| 759 | itr_size = le16_to_cpu(usb_dev->actconfig->desc.wTotalLength); | 752 | itr_size = le16_to_cpu(usb_dev->actconfig->desc.wTotalLength); |
| 760 | while (itr_size >= sizeof(*hdr)) { | 753 | while (itr_size >= sizeof(*hdr)) { |
| 761 | hdr = (struct usb_descriptor_header *) itr; | 754 | hdr = (struct usb_descriptor_header *) itr; |
| 762 | d_printf(3, dev, "Extra device descriptor: " | 755 | dev_dbg(dev, "Extra device descriptor: " |
| 763 | "type %02x/%u bytes @ %zu (%zu left)\n", | 756 | "type %02x/%u bytes @ %zu (%zu left)\n", |
| 764 | hdr->bDescriptorType, hdr->bLength, | 757 | hdr->bDescriptorType, hdr->bLength, |
| 765 | (itr - usb_dev->rawdescriptors[actconfig_idx]), | 758 | (itr - usb_dev->rawdescriptors[actconfig_idx]), |
| 766 | itr_size); | 759 | itr_size); |
| 767 | if (hdr->bDescriptorType == USB_DT_CS_RADIO_CONTROL) | 760 | if (hdr->bDescriptorType == USB_DT_CS_RADIO_CONTROL) |
| 768 | goto found; | 761 | goto found; |
| 769 | itr += hdr->bLength; | 762 | itr += hdr->bLength; |
| @@ -795,8 +788,7 @@ found: | |||
| 795 | goto error; | 788 | goto error; |
| 796 | } | 789 | } |
| 797 | rc->version = version; | 790 | rc->version = version; |
| 798 | d_printf(3, dev, "Device supports WUSB protocol version 0x%04x \n", | 791 | dev_dbg(dev, "Device supports WUSB protocol version 0x%04x \n", rc->version); |
| 799 | rc->version); | ||
| 800 | result = 0; | 792 | result = 0; |
| 801 | error: | 793 | error: |
| 802 | return result; | 794 | return result; |
| @@ -877,11 +869,28 @@ static void hwarc_disconnect(struct usb_interface *iface) | |||
| 877 | uwb_rc_rm(uwb_rc); | 869 | uwb_rc_rm(uwb_rc); |
| 878 | usb_put_intf(hwarc->usb_iface); | 870 | usb_put_intf(hwarc->usb_iface); |
| 879 | usb_put_dev(hwarc->usb_dev); | 871 | usb_put_dev(hwarc->usb_dev); |
| 880 | d_printf(1, &hwarc->usb_iface->dev, "freed hwarc %p\n", hwarc); | ||
| 881 | kfree(hwarc); | 872 | kfree(hwarc); |
| 882 | uwb_rc_put(uwb_rc); /* when creating the device, refcount = 1 */ | 873 | uwb_rc_put(uwb_rc); /* when creating the device, refcount = 1 */ |
| 883 | } | 874 | } |
| 884 | 875 | ||
| 876 | static int hwarc_pre_reset(struct usb_interface *iface) | ||
| 877 | { | ||
| 878 | struct hwarc *hwarc = usb_get_intfdata(iface); | ||
| 879 | struct uwb_rc *uwb_rc = hwarc->uwb_rc; | ||
| 880 | |||
| 881 | uwb_rc_pre_reset(uwb_rc); | ||
| 882 | return 0; | ||
| 883 | } | ||
| 884 | |||
| 885 | static int hwarc_post_reset(struct usb_interface *iface) | ||
| 886 | { | ||
| 887 | struct hwarc *hwarc = usb_get_intfdata(iface); | ||
| 888 | struct uwb_rc *uwb_rc = hwarc->uwb_rc; | ||
| 889 | |||
| 890 | uwb_rc_post_reset(uwb_rc); | ||
| 891 | return 0; | ||
| 892 | } | ||
| 893 | |||
| 885 | /** USB device ID's that we handle */ | 894 | /** USB device ID's that we handle */ |
| 886 | static struct usb_device_id hwarc_id_table[] = { | 895 | static struct usb_device_id hwarc_id_table[] = { |
| 887 | /* D-Link DUB-1210 */ | 896 | /* D-Link DUB-1210 */ |
| @@ -898,20 +907,16 @@ MODULE_DEVICE_TABLE(usb, hwarc_id_table); | |||
| 898 | 907 | ||
| 899 | static struct usb_driver hwarc_driver = { | 908 | static struct usb_driver hwarc_driver = { |
| 900 | .name = "hwa-rc", | 909 | .name = "hwa-rc", |
| 910 | .id_table = hwarc_id_table, | ||
| 901 | .probe = hwarc_probe, | 911 | .probe = hwarc_probe, |
| 902 | .disconnect = hwarc_disconnect, | 912 | .disconnect = hwarc_disconnect, |
| 903 | .id_table = hwarc_id_table, | 913 | .pre_reset = hwarc_pre_reset, |
| 914 | .post_reset = hwarc_post_reset, | ||
| 904 | }; | 915 | }; |
| 905 | 916 | ||
| 906 | static int __init hwarc_driver_init(void) | 917 | static int __init hwarc_driver_init(void) |
| 907 | { | 918 | { |
| 908 | int result; | 919 | return usb_register(&hwarc_driver); |
| 909 | result = usb_register(&hwarc_driver); | ||
| 910 | if (result < 0) | ||
| 911 | printk(KERN_ERR "HWA-RC: Cannot register USB driver: %d\n", | ||
| 912 | result); | ||
| 913 | return result; | ||
| 914 | |||
| 915 | } | 920 | } |
| 916 | module_init(hwarc_driver_init); | 921 | module_init(hwarc_driver_init); |
| 917 | 922 | ||
diff --git a/drivers/uwb/i1480/dfu/dfu.c b/drivers/uwb/i1480/dfu/dfu.c index 9097b3b3038..da7b1d08003 100644 --- a/drivers/uwb/i1480/dfu/dfu.c +++ b/drivers/uwb/i1480/dfu/dfu.c | |||
| @@ -34,10 +34,7 @@ | |||
| 34 | #include <linux/uwb.h> | 34 | #include <linux/uwb.h> |
| 35 | #include <linux/random.h> | 35 | #include <linux/random.h> |
| 36 | 36 | ||
| 37 | #define D_LOCAL 0 | 37 | /* |
| 38 | #include <linux/uwb/debug.h> | ||
| 39 | |||
| 40 | /** | ||
| 41 | * i1480_rceb_check - Check RCEB for expected field values | 38 | * i1480_rceb_check - Check RCEB for expected field values |
| 42 | * @i1480: pointer to device for which RCEB is being checked | 39 | * @i1480: pointer to device for which RCEB is being checked |
| 43 | * @rceb: RCEB being checked | 40 | * @rceb: RCEB being checked |
| @@ -83,7 +80,7 @@ int i1480_rceb_check(const struct i1480 *i1480, const struct uwb_rceb *rceb, | |||
| 83 | EXPORT_SYMBOL_GPL(i1480_rceb_check); | 80 | EXPORT_SYMBOL_GPL(i1480_rceb_check); |
| 84 | 81 | ||
| 85 | 82 | ||
| 86 | /** | 83 | /* |
| 87 | * Execute a Radio Control Command | 84 | * Execute a Radio Control Command |
| 88 | * | 85 | * |
| 89 | * Command data has to be in i1480->cmd_buf. | 86 | * Command data has to be in i1480->cmd_buf. |
| @@ -101,7 +98,6 @@ ssize_t i1480_cmd(struct i1480 *i1480, const char *cmd_name, size_t cmd_size, | |||
| 101 | u8 expected_type = reply->bEventType; | 98 | u8 expected_type = reply->bEventType; |
| 102 | u8 context; | 99 | u8 context; |
| 103 | 100 | ||
| 104 | d_fnstart(3, i1480->dev, "(%p, %s, %zu)\n", i1480, cmd_name, cmd_size); | ||
| 105 | init_completion(&i1480->evt_complete); | 101 | init_completion(&i1480->evt_complete); |
| 106 | i1480->evt_result = -EINPROGRESS; | 102 | i1480->evt_result = -EINPROGRESS; |
| 107 | do { | 103 | do { |
| @@ -150,8 +146,6 @@ ssize_t i1480_cmd(struct i1480 *i1480, const char *cmd_name, size_t cmd_size, | |||
| 150 | result = i1480_rceb_check(i1480, i1480->evt_buf, cmd_name, context, | 146 | result = i1480_rceb_check(i1480, i1480->evt_buf, cmd_name, context, |
| 151 | expected_type, expected_event); | 147 | expected_type, expected_event); |
| 152 | error: | 148 | error: |
| 153 | d_fnend(3, i1480->dev, "(%p, %s, %zu) = %zd\n", | ||
| 154 | i1480, cmd_name, cmd_size, result); | ||
| 155 | return result; | 149 | return result; |
| 156 | } | 150 | } |
| 157 | EXPORT_SYMBOL_GPL(i1480_cmd); | 151 | EXPORT_SYMBOL_GPL(i1480_cmd); |
diff --git a/drivers/uwb/i1480/dfu/mac.c b/drivers/uwb/i1480/dfu/mac.c index 2e4d8f07c16..694d0daf88a 100644 --- a/drivers/uwb/i1480/dfu/mac.c +++ b/drivers/uwb/i1480/dfu/mac.c | |||
| @@ -31,9 +31,6 @@ | |||
| 31 | #include <linux/uwb.h> | 31 | #include <linux/uwb.h> |
| 32 | #include "i1480-dfu.h" | 32 | #include "i1480-dfu.h" |
| 33 | 33 | ||
| 34 | #define D_LOCAL 0 | ||
| 35 | #include <linux/uwb/debug.h> | ||
| 36 | |||
| 37 | /* | 34 | /* |
| 38 | * Descriptor for a continuous segment of MAC fw data | 35 | * Descriptor for a continuous segment of MAC fw data |
| 39 | */ | 36 | */ |
| @@ -184,10 +181,6 @@ ssize_t i1480_fw_cmp(struct i1480 *i1480, struct fw_hdr *hdr) | |||
| 184 | } | 181 | } |
| 185 | if (memcmp(i1480->cmd_buf, bin + src_itr, result)) { | 182 | if (memcmp(i1480->cmd_buf, bin + src_itr, result)) { |
| 186 | u8 *buf = i1480->cmd_buf; | 183 | u8 *buf = i1480->cmd_buf; |
| 187 | d_printf(2, i1480->dev, | ||
| 188 | "original data @ %p + %u, %zu bytes\n", | ||
| 189 | bin, src_itr, result); | ||
| 190 | d_dump(4, i1480->dev, bin + src_itr, result); | ||
| 191 | for (cnt = 0; cnt < result; cnt++) | 184 | for (cnt = 0; cnt < result; cnt++) |
| 192 | if (bin[src_itr + cnt] != buf[cnt]) { | 185 | if (bin[src_itr + cnt] != buf[cnt]) { |
| 193 | dev_err(i1480->dev, "byte failed at " | 186 | dev_err(i1480->dev, "byte failed at " |
| @@ -224,7 +217,6 @@ int mac_fw_hdrs_push(struct i1480 *i1480, struct fw_hdr *hdr, | |||
| 224 | struct fw_hdr *hdr_itr; | 217 | struct fw_hdr *hdr_itr; |
| 225 | int verif_retry_count; | 218 | int verif_retry_count; |
| 226 | 219 | ||
| 227 | d_fnstart(3, dev, "(%p, %p)\n", i1480, hdr); | ||
| 228 | /* Now, header by header, push them to the hw */ | 220 | /* Now, header by header, push them to the hw */ |
| 229 | for (hdr_itr = hdr; hdr_itr != NULL; hdr_itr = hdr_itr->next) { | 221 | for (hdr_itr = hdr; hdr_itr != NULL; hdr_itr = hdr_itr->next) { |
| 230 | verif_retry_count = 0; | 222 | verif_retry_count = 0; |
| @@ -264,7 +256,6 @@ retry: | |||
| 264 | break; | 256 | break; |
| 265 | } | 257 | } |
| 266 | } | 258 | } |
| 267 | d_fnend(3, dev, "(%zd)\n", result); | ||
| 268 | return result; | 259 | return result; |
| 269 | } | 260 | } |
| 270 | 261 | ||
| @@ -337,11 +328,9 @@ int __mac_fw_upload(struct i1480 *i1480, const char *fw_name, | |||
| 337 | const struct firmware *fw; | 328 | const struct firmware *fw; |
| 338 | struct fw_hdr *fw_hdrs; | 329 | struct fw_hdr *fw_hdrs; |
| 339 | 330 | ||
| 340 | d_fnstart(3, i1480->dev, "(%p, %s, %s)\n", i1480, fw_name, fw_tag); | ||
| 341 | result = request_firmware(&fw, fw_name, i1480->dev); | 331 | result = request_firmware(&fw, fw_name, i1480->dev); |
| 342 | if (result < 0) /* Up to caller to complain on -ENOENT */ | 332 | if (result < 0) /* Up to caller to complain on -ENOENT */ |
| 343 | goto out; | 333 | goto out; |
| 344 | d_printf(3, i1480->dev, "%s fw '%s': uploading\n", fw_tag, fw_name); | ||
| 345 | result = fw_hdrs_load(i1480, &fw_hdrs, fw->data, fw->size); | 334 | result = fw_hdrs_load(i1480, &fw_hdrs, fw->data, fw->size); |
| 346 | if (result < 0) { | 335 | if (result < 0) { |
| 347 | dev_err(i1480->dev, "%s fw '%s': failed to parse firmware " | 336 | dev_err(i1480->dev, "%s fw '%s': failed to parse firmware " |
| @@ -363,8 +352,6 @@ out_hdrs_release: | |||
| 363 | out_release: | 352 | out_release: |
| 364 | release_firmware(fw); | 353 | release_firmware(fw); |
| 365 | out: | 354 | out: |
| 366 | d_fnend(3, i1480->dev, "(%p, %s, %s) = %d\n", i1480, fw_name, fw_tag, | ||
| 367 | result); | ||
| 368 | return result; | 355 | return result; |
| 369 | } | 356 | } |
| 370 | 357 | ||
| @@ -433,7 +420,6 @@ int i1480_fw_is_running_q(struct i1480 *i1480) | |||
| 433 | int result; | 420 | int result; |
| 434 | u32 *val = (u32 *) i1480->cmd_buf; | 421 | u32 *val = (u32 *) i1480->cmd_buf; |
| 435 | 422 | ||
| 436 | d_fnstart(3, i1480->dev, "(i1480 %p)\n", i1480); | ||
| 437 | for (cnt = 0; cnt < 10; cnt++) { | 423 | for (cnt = 0; cnt < 10; cnt++) { |
| 438 | msleep(100); | 424 | msleep(100); |
| 439 | result = i1480->read(i1480, 0x80080000, 4); | 425 | result = i1480->read(i1480, 0x80080000, 4); |
| @@ -447,7 +433,6 @@ int i1480_fw_is_running_q(struct i1480 *i1480) | |||
| 447 | dev_err(i1480->dev, "Timed out waiting for fw to start\n"); | 433 | dev_err(i1480->dev, "Timed out waiting for fw to start\n"); |
| 448 | result = -ETIMEDOUT; | 434 | result = -ETIMEDOUT; |
| 449 | out: | 435 | out: |
| 450 | d_fnend(3, i1480->dev, "(i1480 %p) = %d\n", i1480, result); | ||
| 451 | return result; | 436 | return result; |
| 452 | 437 | ||
| 453 | } | 438 | } |
| @@ -467,7 +452,6 @@ int i1480_mac_fw_upload(struct i1480 *i1480) | |||
| 467 | int result = 0, deprecated_name = 0; | 452 | int result = 0, deprecated_name = 0; |
| 468 | struct i1480_rceb *rcebe = (void *) i1480->evt_buf; | 453 | struct i1480_rceb *rcebe = (void *) i1480->evt_buf; |
| 469 | 454 | ||
| 470 | d_fnstart(3, i1480->dev, "(%p)\n", i1480); | ||
| 471 | result = __mac_fw_upload(i1480, i1480->mac_fw_name, "MAC"); | 455 | result = __mac_fw_upload(i1480, i1480->mac_fw_name, "MAC"); |
| 472 | if (result == -ENOENT) { | 456 | if (result == -ENOENT) { |
| 473 | result = __mac_fw_upload(i1480, i1480->mac_fw_name_deprecate, | 457 | result = __mac_fw_upload(i1480, i1480->mac_fw_name_deprecate, |
| @@ -501,7 +485,6 @@ int i1480_mac_fw_upload(struct i1480 *i1480) | |||
| 501 | dev_err(i1480->dev, "MAC fw '%s': initialization event returns " | 485 | dev_err(i1480->dev, "MAC fw '%s': initialization event returns " |
| 502 | "wrong size (%zu bytes vs %zu needed)\n", | 486 | "wrong size (%zu bytes vs %zu needed)\n", |
| 503 | i1480->mac_fw_name, i1480->evt_result, sizeof(*rcebe)); | 487 | i1480->mac_fw_name, i1480->evt_result, sizeof(*rcebe)); |
| 504 | dump_bytes(i1480->dev, rcebe, min(i1480->evt_result, (ssize_t)32)); | ||
| 505 | goto error_size; | 488 | goto error_size; |
| 506 | } | 489 | } |
| 507 | result = -EIO; | 490 | result = -EIO; |
| @@ -522,6 +505,5 @@ error_fw_not_running: | |||
| 522 | error_init_timeout: | 505 | error_init_timeout: |
| 523 | error_size: | 506 | error_size: |
| 524 | error_setup: | 507 | error_setup: |
| 525 | d_fnend(3, i1480->dev, "(i1480 %p) = %d\n", i1480, result); | ||
| 526 | return result; | 508 | return result; |
| 527 | } | 509 | } |
diff --git a/drivers/uwb/i1480/dfu/usb.c b/drivers/uwb/i1480/dfu/usb.c index 98eeeff051a..686795e9719 100644 --- a/drivers/uwb/i1480/dfu/usb.c +++ b/drivers/uwb/i1480/dfu/usb.c | |||
| @@ -35,7 +35,6 @@ | |||
| 35 | * the functions are i1480_usb_NAME(). | 35 | * the functions are i1480_usb_NAME(). |
| 36 | */ | 36 | */ |
| 37 | #include <linux/module.h> | 37 | #include <linux/module.h> |
| 38 | #include <linux/version.h> | ||
| 39 | #include <linux/usb.h> | 38 | #include <linux/usb.h> |
| 40 | #include <linux/interrupt.h> | 39 | #include <linux/interrupt.h> |
| 41 | #include <linux/delay.h> | 40 | #include <linux/delay.h> |
| @@ -44,10 +43,6 @@ | |||
| 44 | #include <linux/usb/wusb-wa.h> | 43 | #include <linux/usb/wusb-wa.h> |
| 45 | #include "i1480-dfu.h" | 44 | #include "i1480-dfu.h" |
| 46 | 45 | ||
| 47 | #define D_LOCAL 0 | ||
| 48 | #include <linux/uwb/debug.h> | ||
| 49 | |||
| 50 | |||
| 51 | struct i1480_usb { | 46 | struct i1480_usb { |
| 52 | struct i1480 i1480; | 47 | struct i1480 i1480; |
| 53 | struct usb_device *usb_dev; | 48 | struct usb_device *usb_dev; |
| @@ -118,8 +113,6 @@ int i1480_usb_write(struct i1480 *i1480, u32 memory_address, | |||
| 118 | struct i1480_usb *i1480_usb = container_of(i1480, struct i1480_usb, i1480); | 113 | struct i1480_usb *i1480_usb = container_of(i1480, struct i1480_usb, i1480); |
| 119 | size_t buffer_size, itr = 0; | 114 | size_t buffer_size, itr = 0; |
| 120 | 115 | ||
| 121 | d_fnstart(3, i1480->dev, "(%p, 0x%08x, %p, %zu)\n", | ||
| 122 | i1480, memory_address, buffer, size); | ||
| 123 | BUG_ON(size & 0x3); /* Needs to be a multiple of 4 */ | 116 | BUG_ON(size & 0x3); /* Needs to be a multiple of 4 */ |
| 124 | while (size > 0) { | 117 | while (size > 0) { |
| 125 | buffer_size = size < i1480->buf_size ? size : i1480->buf_size; | 118 | buffer_size = size < i1480->buf_size ? size : i1480->buf_size; |
| @@ -132,16 +125,10 @@ int i1480_usb_write(struct i1480 *i1480, u32 memory_address, | |||
| 132 | i1480->cmd_buf, buffer_size, 100 /* FIXME: arbitrary */); | 125 | i1480->cmd_buf, buffer_size, 100 /* FIXME: arbitrary */); |
| 133 | if (result < 0) | 126 | if (result < 0) |
| 134 | break; | 127 | break; |
| 135 | d_printf(3, i1480->dev, | ||
| 136 | "wrote @ 0x%08x %u bytes (of %zu bytes requested)\n", | ||
| 137 | memory_address, result, buffer_size); | ||
| 138 | d_dump(4, i1480->dev, i1480->cmd_buf, result); | ||
| 139 | itr += result; | 128 | itr += result; |
| 140 | memory_address += result; | 129 | memory_address += result; |
| 141 | size -= result; | 130 | size -= result; |
| 142 | } | 131 | } |
| 143 | d_fnend(3, i1480->dev, "(%p, 0x%08x, %p, %zu) = %d\n", | ||
| 144 | i1480, memory_address, buffer, size, result); | ||
| 145 | return result; | 132 | return result; |
| 146 | } | 133 | } |
| 147 | 134 | ||
| @@ -166,8 +153,6 @@ int i1480_usb_read(struct i1480 *i1480, u32 addr, size_t size) | |||
| 166 | size_t itr, read_size = i1480->buf_size; | 153 | size_t itr, read_size = i1480->buf_size; |
| 167 | struct i1480_usb *i1480_usb = container_of(i1480, struct i1480_usb, i1480); | 154 | struct i1480_usb *i1480_usb = container_of(i1480, struct i1480_usb, i1480); |
| 168 | 155 | ||
| 169 | d_fnstart(3, i1480->dev, "(%p, 0x%08x, %zu)\n", | ||
| 170 | i1480, addr, size); | ||
| 171 | BUG_ON(size > i1480->buf_size); | 156 | BUG_ON(size > i1480->buf_size); |
| 172 | BUG_ON(size & 0x3); /* Needs to be a multiple of 4 */ | 157 | BUG_ON(size & 0x3); /* Needs to be a multiple of 4 */ |
| 173 | BUG_ON(read_size > 512); | 158 | BUG_ON(read_size > 512); |
| @@ -201,10 +186,6 @@ int i1480_usb_read(struct i1480 *i1480, u32 addr, size_t size) | |||
| 201 | } | 186 | } |
| 202 | result = bytes; | 187 | result = bytes; |
| 203 | out: | 188 | out: |
| 204 | d_fnend(3, i1480->dev, "(%p, 0x%08x, %zu) = %zd\n", | ||
| 205 | i1480, addr, size, result); | ||
| 206 | if (result > 0) | ||
| 207 | d_dump(4, i1480->dev, i1480->cmd_buf, result); | ||
| 208 | return result; | 189 | return result; |
| 209 | } | 190 | } |
| 210 | 191 | ||
| @@ -260,7 +241,6 @@ int i1480_usb_wait_init_done(struct i1480 *i1480) | |||
| 260 | struct i1480_usb *i1480_usb = container_of(i1480, struct i1480_usb, i1480); | 241 | struct i1480_usb *i1480_usb = container_of(i1480, struct i1480_usb, i1480); |
| 261 | struct usb_endpoint_descriptor *epd; | 242 | struct usb_endpoint_descriptor *epd; |
| 262 | 243 | ||
| 263 | d_fnstart(3, dev, "(%p)\n", i1480); | ||
| 264 | init_completion(&i1480->evt_complete); | 244 | init_completion(&i1480->evt_complete); |
| 265 | i1480->evt_result = -EINPROGRESS; | 245 | i1480->evt_result = -EINPROGRESS; |
| 266 | epd = &i1480_usb->usb_iface->cur_altsetting->endpoint[0].desc; | 246 | epd = &i1480_usb->usb_iface->cur_altsetting->endpoint[0].desc; |
| @@ -282,14 +262,12 @@ int i1480_usb_wait_init_done(struct i1480 *i1480) | |||
| 282 | goto error_wait; | 262 | goto error_wait; |
| 283 | } | 263 | } |
| 284 | usb_kill_urb(i1480_usb->neep_urb); | 264 | usb_kill_urb(i1480_usb->neep_urb); |
| 285 | d_fnend(3, dev, "(%p) = 0\n", i1480); | ||
| 286 | return 0; | 265 | return 0; |
| 287 | 266 | ||
| 288 | error_wait: | 267 | error_wait: |
| 289 | usb_kill_urb(i1480_usb->neep_urb); | 268 | usb_kill_urb(i1480_usb->neep_urb); |
| 290 | error_submit: | 269 | error_submit: |
| 291 | i1480->evt_result = result; | 270 | i1480->evt_result = result; |
| 292 | d_fnend(3, dev, "(%p) = %d\n", i1480, result); | ||
| 293 | return result; | 271 | return result; |
| 294 | } | 272 | } |
| 295 | 273 | ||
| @@ -320,7 +298,6 @@ int i1480_usb_cmd(struct i1480 *i1480, const char *cmd_name, size_t cmd_size) | |||
| 320 | struct uwb_rccb *cmd = i1480->cmd_buf; | 298 | struct uwb_rccb *cmd = i1480->cmd_buf; |
| 321 | u8 iface_no; | 299 | u8 iface_no; |
| 322 | 300 | ||
| 323 | d_fnstart(3, dev, "(%p, %s, %zu)\n", i1480, cmd_name, cmd_size); | ||
| 324 | /* Post a read on the notification & event endpoint */ | 301 | /* Post a read on the notification & event endpoint */ |
| 325 | iface_no = i1480_usb->usb_iface->cur_altsetting->desc.bInterfaceNumber; | 302 | iface_no = i1480_usb->usb_iface->cur_altsetting->desc.bInterfaceNumber; |
| 326 | epd = &i1480_usb->usb_iface->cur_altsetting->endpoint[0].desc; | 303 | epd = &i1480_usb->usb_iface->cur_altsetting->endpoint[0].desc; |
| @@ -348,15 +325,11 @@ int i1480_usb_cmd(struct i1480 *i1480, const char *cmd_name, size_t cmd_size) | |||
| 348 | cmd_name, result); | 325 | cmd_name, result); |
| 349 | goto error_submit_ep0; | 326 | goto error_submit_ep0; |
| 350 | } | 327 | } |
| 351 | d_fnend(3, dev, "(%p, %s, %zu) = %d\n", | ||
| 352 | i1480, cmd_name, cmd_size, result); | ||
| 353 | return result; | 328 | return result; |
| 354 | 329 | ||
| 355 | error_submit_ep0: | 330 | error_submit_ep0: |
| 356 | usb_kill_urb(i1480_usb->neep_urb); | 331 | usb_kill_urb(i1480_usb->neep_urb); |
| 357 | error_submit_ep1: | 332 | error_submit_ep1: |
| 358 | d_fnend(3, dev, "(%p, %s, %zu) = %d\n", | ||
| 359 | i1480, cmd_name, cmd_size, result); | ||
| 360 | return result; | 333 | return result; |
| 361 | } | 334 | } |
| 362 | 335 | ||
diff --git a/drivers/uwb/i1480/i1480u-wlp/lc.c b/drivers/uwb/i1480/i1480u-wlp/lc.c index 737d60cd5b7..049c05d4cc6 100644 --- a/drivers/uwb/i1480/i1480u-wlp/lc.c +++ b/drivers/uwb/i1480/i1480u-wlp/lc.c | |||
| @@ -55,10 +55,9 @@ | |||
| 55 | * is being removed. | 55 | * is being removed. |
| 56 | * i1480u_rm() | 56 | * i1480u_rm() |
| 57 | */ | 57 | */ |
| 58 | #include <linux/version.h> | ||
| 59 | #include <linux/if_arp.h> | 58 | #include <linux/if_arp.h> |
| 60 | #include <linux/etherdevice.h> | 59 | #include <linux/etherdevice.h> |
| 61 | #include <linux/uwb/debug.h> | 60 | |
| 62 | #include "i1480u-wlp.h" | 61 | #include "i1480u-wlp.h" |
| 63 | 62 | ||
| 64 | 63 | ||
| @@ -207,7 +206,7 @@ int i1480u_add(struct i1480u *i1480u, struct usb_interface *iface) | |||
| 207 | wlp->fill_device_info = i1480u_fill_device_info; | 206 | wlp->fill_device_info = i1480u_fill_device_info; |
| 208 | wlp->stop_queue = i1480u_stop_queue; | 207 | wlp->stop_queue = i1480u_stop_queue; |
| 209 | wlp->start_queue = i1480u_start_queue; | 208 | wlp->start_queue = i1480u_start_queue; |
| 210 | result = wlp_setup(wlp, rc); | 209 | result = wlp_setup(wlp, rc, net_dev); |
| 211 | if (result < 0) { | 210 | if (result < 0) { |
| 212 | dev_err(&iface->dev, "Cannot setup WLP\n"); | 211 | dev_err(&iface->dev, "Cannot setup WLP\n"); |
| 213 | goto error_wlp_setup; | 212 | goto error_wlp_setup; |
diff --git a/drivers/uwb/i1480/i1480u-wlp/netdev.c b/drivers/uwb/i1480/i1480u-wlp/netdev.c index 8802ac43d87..e3873ffb942 100644 --- a/drivers/uwb/i1480/i1480u-wlp/netdev.c +++ b/drivers/uwb/i1480/i1480u-wlp/netdev.c | |||
| @@ -41,7 +41,7 @@ | |||
| 41 | 41 | ||
| 42 | #include <linux/if_arp.h> | 42 | #include <linux/if_arp.h> |
| 43 | #include <linux/etherdevice.h> | 43 | #include <linux/etherdevice.h> |
| 44 | #include <linux/uwb/debug.h> | 44 | |
| 45 | #include "i1480u-wlp.h" | 45 | #include "i1480u-wlp.h" |
| 46 | 46 | ||
| 47 | struct i1480u_cmd_set_ip_mas { | 47 | struct i1480u_cmd_set_ip_mas { |
| @@ -207,6 +207,11 @@ int i1480u_open(struct net_device *net_dev) | |||
| 207 | result = i1480u_rx_setup(i1480u); /* Alloc RX stuff */ | 207 | result = i1480u_rx_setup(i1480u); /* Alloc RX stuff */ |
| 208 | if (result < 0) | 208 | if (result < 0) |
| 209 | goto error_rx_setup; | 209 | goto error_rx_setup; |
| 210 | |||
| 211 | result = uwb_radio_start(&wlp->pal); | ||
| 212 | if (result < 0) | ||
| 213 | goto error_radio_start; | ||
| 214 | |||
| 210 | netif_wake_queue(net_dev); | 215 | netif_wake_queue(net_dev); |
| 211 | #ifdef i1480u_FLOW_CONTROL | 216 | #ifdef i1480u_FLOW_CONTROL |
| 212 | result = usb_submit_urb(i1480u->notif_urb, GFP_KERNEL);; | 217 | result = usb_submit_urb(i1480u->notif_urb, GFP_KERNEL);; |
| @@ -215,25 +220,20 @@ int i1480u_open(struct net_device *net_dev) | |||
| 215 | goto error_notif_urb_submit; | 220 | goto error_notif_urb_submit; |
| 216 | } | 221 | } |
| 217 | #endif | 222 | #endif |
| 218 | i1480u->uwb_notifs_handler.cb = i1480u_uwb_notifs_cb; | ||
| 219 | i1480u->uwb_notifs_handler.data = i1480u; | ||
| 220 | if (uwb_bg_joined(rc)) | ||
| 221 | netif_carrier_on(net_dev); | ||
| 222 | else | ||
| 223 | netif_carrier_off(net_dev); | ||
| 224 | uwb_notifs_register(rc, &i1480u->uwb_notifs_handler); | ||
| 225 | /* Interface is up with an address, now we can create WSS */ | 223 | /* Interface is up with an address, now we can create WSS */ |
| 226 | result = wlp_wss_setup(net_dev, &wlp->wss); | 224 | result = wlp_wss_setup(net_dev, &wlp->wss); |
| 227 | if (result < 0) { | 225 | if (result < 0) { |
| 228 | dev_err(dev, "Can't create WSS: %d. \n", result); | 226 | dev_err(dev, "Can't create WSS: %d. \n", result); |
| 229 | goto error_notif_deregister; | 227 | goto error_wss_setup; |
| 230 | } | 228 | } |
| 231 | return 0; | 229 | return 0; |
| 232 | error_notif_deregister: | 230 | error_wss_setup: |
| 233 | uwb_notifs_deregister(rc, &i1480u->uwb_notifs_handler); | ||
| 234 | #ifdef i1480u_FLOW_CONTROL | 231 | #ifdef i1480u_FLOW_CONTROL |
| 232 | usb_kill_urb(i1480u->notif_urb); | ||
| 235 | error_notif_urb_submit: | 233 | error_notif_urb_submit: |
| 236 | #endif | 234 | #endif |
| 235 | uwb_radio_stop(&wlp->pal); | ||
| 236 | error_radio_start: | ||
| 237 | netif_stop_queue(net_dev); | 237 | netif_stop_queue(net_dev); |
| 238 | i1480u_rx_release(i1480u); | 238 | i1480u_rx_release(i1480u); |
| 239 | error_rx_setup: | 239 | error_rx_setup: |
| @@ -248,16 +248,15 @@ int i1480u_stop(struct net_device *net_dev) | |||
| 248 | { | 248 | { |
| 249 | struct i1480u *i1480u = netdev_priv(net_dev); | 249 | struct i1480u *i1480u = netdev_priv(net_dev); |
| 250 | struct wlp *wlp = &i1480u->wlp; | 250 | struct wlp *wlp = &i1480u->wlp; |
| 251 | struct uwb_rc *rc = wlp->rc; | ||
| 252 | 251 | ||
| 253 | BUG_ON(wlp->rc == NULL); | 252 | BUG_ON(wlp->rc == NULL); |
| 254 | wlp_wss_remove(&wlp->wss); | 253 | wlp_wss_remove(&wlp->wss); |
| 255 | uwb_notifs_deregister(rc, &i1480u->uwb_notifs_handler); | ||
| 256 | netif_carrier_off(net_dev); | 254 | netif_carrier_off(net_dev); |
| 257 | #ifdef i1480u_FLOW_CONTROL | 255 | #ifdef i1480u_FLOW_CONTROL |
| 258 | usb_kill_urb(i1480u->notif_urb); | 256 | usb_kill_urb(i1480u->notif_urb); |
| 259 | #endif | 257 | #endif |
| 260 | netif_stop_queue(net_dev); | 258 | netif_stop_queue(net_dev); |
| 259 | uwb_radio_stop(&wlp->pal); | ||
| 261 | i1480u_rx_release(i1480u); | 260 | i1480u_rx_release(i1480u); |
| 262 | i1480u_tx_release(i1480u); | 261 | i1480u_tx_release(i1480u); |
| 263 | return 0; | 262 | return 0; |
| @@ -303,34 +302,6 @@ int i1480u_change_mtu(struct net_device *net_dev, int mtu) | |||
| 303 | return 0; | 302 | return 0; |
| 304 | } | 303 | } |
| 305 | 304 | ||
| 306 | |||
| 307 | /** | ||
| 308 | * Callback function to handle events from UWB | ||
| 309 | * When we see other devices we know the carrier is ok, | ||
| 310 | * if we are the only device in the beacon group we set the carrier | ||
| 311 | * state to off. | ||
| 312 | * */ | ||
| 313 | void i1480u_uwb_notifs_cb(void *data, struct uwb_dev *uwb_dev, | ||
| 314 | enum uwb_notifs event) | ||
| 315 | { | ||
| 316 | struct i1480u *i1480u = data; | ||
| 317 | struct net_device *net_dev = i1480u->net_dev; | ||
| 318 | struct device *dev = &i1480u->usb_iface->dev; | ||
| 319 | switch (event) { | ||
| 320 | case UWB_NOTIF_BG_JOIN: | ||
| 321 | netif_carrier_on(net_dev); | ||
| 322 | dev_info(dev, "Link is up\n"); | ||
| 323 | break; | ||
| 324 | case UWB_NOTIF_BG_LEAVE: | ||
| 325 | netif_carrier_off(net_dev); | ||
| 326 | dev_info(dev, "Link is down\n"); | ||
| 327 | break; | ||
| 328 | default: | ||
| 329 | dev_err(dev, "don't know how to handle event %d from uwb\n", | ||
| 330 | event); | ||
| 331 | } | ||
| 332 | } | ||
| 333 | |||
| 334 | /** | 305 | /** |
| 335 | * Stop the network queue | 306 | * Stop the network queue |
| 336 | * | 307 | * |
diff --git a/drivers/uwb/i1480/i1480u-wlp/rx.c b/drivers/uwb/i1480/i1480u-wlp/rx.c index 9fc035354a7..34f4cf9a7d3 100644 --- a/drivers/uwb/i1480/i1480u-wlp/rx.c +++ b/drivers/uwb/i1480/i1480u-wlp/rx.c | |||
| @@ -68,11 +68,7 @@ | |||
| 68 | #include <linux/etherdevice.h> | 68 | #include <linux/etherdevice.h> |
| 69 | #include "i1480u-wlp.h" | 69 | #include "i1480u-wlp.h" |
| 70 | 70 | ||
| 71 | #define D_LOCAL 0 | 71 | /* |
| 72 | #include <linux/uwb/debug.h> | ||
| 73 | |||
| 74 | |||
| 75 | /** | ||
| 76 | * Setup the RX context | 72 | * Setup the RX context |
| 77 | * | 73 | * |
| 78 | * Each URB is provided with a transfer_buffer that is the data field | 74 | * Each URB is provided with a transfer_buffer that is the data field |
| @@ -129,7 +125,7 @@ error: | |||
| 129 | } | 125 | } |
| 130 | 126 | ||
| 131 | 127 | ||
| 132 | /** Release resources associated to the rx context */ | 128 | /* Release resources associated to the rx context */ |
| 133 | void i1480u_rx_release(struct i1480u *i1480u) | 129 | void i1480u_rx_release(struct i1480u *i1480u) |
| 134 | { | 130 | { |
| 135 | int cnt; | 131 | int cnt; |
| @@ -155,7 +151,7 @@ void i1480u_rx_unlink_urbs(struct i1480u *i1480u) | |||
| 155 | } | 151 | } |
| 156 | } | 152 | } |
| 157 | 153 | ||
| 158 | /** Fix an out-of-sequence packet */ | 154 | /* Fix an out-of-sequence packet */ |
| 159 | #define i1480u_fix(i1480u, msg...) \ | 155 | #define i1480u_fix(i1480u, msg...) \ |
| 160 | do { \ | 156 | do { \ |
| 161 | if (printk_ratelimit()) \ | 157 | if (printk_ratelimit()) \ |
| @@ -166,7 +162,7 @@ do { \ | |||
| 166 | } while (0) | 162 | } while (0) |
| 167 | 163 | ||
| 168 | 164 | ||
| 169 | /** Drop an out-of-sequence packet */ | 165 | /* Drop an out-of-sequence packet */ |
| 170 | #define i1480u_drop(i1480u, msg...) \ | 166 | #define i1480u_drop(i1480u, msg...) \ |
| 171 | do { \ | 167 | do { \ |
| 172 | if (printk_ratelimit()) \ | 168 | if (printk_ratelimit()) \ |
| @@ -177,7 +173,7 @@ do { \ | |||
| 177 | 173 | ||
| 178 | 174 | ||
| 179 | 175 | ||
| 180 | /** Finalizes setting up the SKB and delivers it | 176 | /* Finalizes setting up the SKB and delivers it |
| 181 | * | 177 | * |
| 182 | * We first pass the incoming frame to WLP substack for verification. It | 178 | * We first pass the incoming frame to WLP substack for verification. It |
| 183 | * may also be a WLP association frame in which case WLP will take over the | 179 | * may also be a WLP association frame in which case WLP will take over the |
| @@ -192,18 +188,11 @@ void i1480u_skb_deliver(struct i1480u *i1480u) | |||
| 192 | struct net_device *net_dev = i1480u->net_dev; | 188 | struct net_device *net_dev = i1480u->net_dev; |
| 193 | struct device *dev = &i1480u->usb_iface->dev; | 189 | struct device *dev = &i1480u->usb_iface->dev; |
| 194 | 190 | ||
| 195 | d_printf(6, dev, "RX delivered pre skb(%p), %u bytes\n", | ||
| 196 | i1480u->rx_skb, i1480u->rx_skb->len); | ||
| 197 | d_dump(7, dev, i1480u->rx_skb->data, i1480u->rx_skb->len); | ||
| 198 | should_parse = wlp_receive_frame(dev, &i1480u->wlp, i1480u->rx_skb, | 191 | should_parse = wlp_receive_frame(dev, &i1480u->wlp, i1480u->rx_skb, |
| 199 | &i1480u->rx_srcaddr); | 192 | &i1480u->rx_srcaddr); |
| 200 | if (!should_parse) | 193 | if (!should_parse) |
| 201 | goto out; | 194 | goto out; |
| 202 | i1480u->rx_skb->protocol = eth_type_trans(i1480u->rx_skb, net_dev); | 195 | i1480u->rx_skb->protocol = eth_type_trans(i1480u->rx_skb, net_dev); |
| 203 | d_printf(5, dev, "RX delivered skb(%p), %u bytes\n", | ||
| 204 | i1480u->rx_skb, i1480u->rx_skb->len); | ||
| 205 | d_dump(7, dev, i1480u->rx_skb->data, | ||
| 206 | i1480u->rx_skb->len > 72 ? 72 : i1480u->rx_skb->len); | ||
| 207 | i1480u->stats.rx_packets++; | 196 | i1480u->stats.rx_packets++; |
| 208 | i1480u->stats.rx_bytes += i1480u->rx_untd_pkt_size; | 197 | i1480u->stats.rx_bytes += i1480u->rx_untd_pkt_size; |
| 209 | net_dev->last_rx = jiffies; | 198 | net_dev->last_rx = jiffies; |
| @@ -216,7 +205,7 @@ out: | |||
| 216 | } | 205 | } |
| 217 | 206 | ||
| 218 | 207 | ||
| 219 | /** | 208 | /* |
| 220 | * Process a buffer of data received from the USB RX endpoint | 209 | * Process a buffer of data received from the USB RX endpoint |
| 221 | * | 210 | * |
| 222 | * First fragment arrives with next or last fragment. All other fragments | 211 | * First fragment arrives with next or last fragment. All other fragments |
| @@ -404,7 +393,7 @@ out: | |||
| 404 | } | 393 | } |
| 405 | 394 | ||
| 406 | 395 | ||
| 407 | /** | 396 | /* |
| 408 | * Called when an RX URB has finished receiving or has found some kind | 397 | * Called when an RX URB has finished receiving or has found some kind |
| 409 | * of error condition. | 398 | * of error condition. |
| 410 | * | 399 | * |
diff --git a/drivers/uwb/i1480/i1480u-wlp/sysfs.c b/drivers/uwb/i1480/i1480u-wlp/sysfs.c index a1d8ca6ac93..4ffaf546cc6 100644 --- a/drivers/uwb/i1480/i1480u-wlp/sysfs.c +++ b/drivers/uwb/i1480/i1480u-wlp/sysfs.c | |||
| @@ -25,8 +25,8 @@ | |||
| 25 | 25 | ||
| 26 | #include <linux/netdevice.h> | 26 | #include <linux/netdevice.h> |
| 27 | #include <linux/etherdevice.h> | 27 | #include <linux/etherdevice.h> |
| 28 | #include <linux/uwb/debug.h> | ||
| 29 | #include <linux/device.h> | 28 | #include <linux/device.h> |
| 29 | |||
| 30 | #include "i1480u-wlp.h" | 30 | #include "i1480u-wlp.h" |
| 31 | 31 | ||
| 32 | 32 | ||
| @@ -226,7 +226,6 @@ ssize_t wlp_tx_inflight_store(struct i1480u_tx_inflight *inflight, | |||
| 226 | * (CLASS_DEVICE_ATTR or DEVICE_ATTR) and i1480u_ATTR_NAME produces a | 226 | * (CLASS_DEVICE_ATTR or DEVICE_ATTR) and i1480u_ATTR_NAME produces a |
| 227 | * class_device_attr_NAME or device_attr_NAME (for group registration). | 227 | * class_device_attr_NAME or device_attr_NAME (for group registration). |
| 228 | */ | 228 | */ |
| 229 | #include <linux/version.h> | ||
| 230 | 229 | ||
| 231 | #define i1480u_SHOW(name, fn, param) \ | 230 | #define i1480u_SHOW(name, fn, param) \ |
| 232 | static ssize_t i1480u_show_##name(struct device *dev, \ | 231 | static ssize_t i1480u_show_##name(struct device *dev, \ |
diff --git a/drivers/uwb/i1480/i1480u-wlp/tx.c b/drivers/uwb/i1480/i1480u-wlp/tx.c index 3426bfb6824..39032cc3503 100644 --- a/drivers/uwb/i1480/i1480u-wlp/tx.c +++ b/drivers/uwb/i1480/i1480u-wlp/tx.c | |||
| @@ -55,8 +55,6 @@ | |||
| 55 | */ | 55 | */ |
| 56 | 56 | ||
| 57 | #include "i1480u-wlp.h" | 57 | #include "i1480u-wlp.h" |
| 58 | #define D_LOCAL 5 | ||
| 59 | #include <linux/uwb/debug.h> | ||
| 60 | 58 | ||
| 61 | enum { | 59 | enum { |
| 62 | /* This is only for Next and Last TX packets */ | 60 | /* This is only for Next and Last TX packets */ |
| @@ -64,7 +62,7 @@ enum { | |||
| 64 | - sizeof(struct untd_hdr_rst), | 62 | - sizeof(struct untd_hdr_rst), |
| 65 | }; | 63 | }; |
| 66 | 64 | ||
| 67 | /** Free resources allocated to a i1480u tx context. */ | 65 | /* Free resources allocated to a i1480u tx context. */ |
| 68 | static | 66 | static |
| 69 | void i1480u_tx_free(struct i1480u_tx *wtx) | 67 | void i1480u_tx_free(struct i1480u_tx *wtx) |
| 70 | { | 68 | { |
| @@ -99,7 +97,7 @@ void i1480u_tx_unlink_urbs(struct i1480u *i1480u) | |||
| 99 | } | 97 | } |
| 100 | 98 | ||
| 101 | 99 | ||
| 102 | /** | 100 | /* |
| 103 | * Callback for a completed tx USB URB. | 101 | * Callback for a completed tx USB URB. |
| 104 | * | 102 | * |
| 105 | * TODO: | 103 | * TODO: |
| @@ -149,8 +147,6 @@ void i1480u_tx_cb(struct urb *urb) | |||
| 149 | <= i1480u->tx_inflight.threshold | 147 | <= i1480u->tx_inflight.threshold |
| 150 | && netif_queue_stopped(net_dev) | 148 | && netif_queue_stopped(net_dev) |
| 151 | && i1480u->tx_inflight.threshold != 0) { | 149 | && i1480u->tx_inflight.threshold != 0) { |
| 152 | if (d_test(2) && printk_ratelimit()) | ||
| 153 | d_printf(2, dev, "Restart queue. \n"); | ||
| 154 | netif_start_queue(net_dev); | 150 | netif_start_queue(net_dev); |
| 155 | atomic_inc(&i1480u->tx_inflight.restart_count); | 151 | atomic_inc(&i1480u->tx_inflight.restart_count); |
| 156 | } | 152 | } |
| @@ -158,7 +154,7 @@ void i1480u_tx_cb(struct urb *urb) | |||
| 158 | } | 154 | } |
| 159 | 155 | ||
| 160 | 156 | ||
| 161 | /** | 157 | /* |
| 162 | * Given a buffer that doesn't fit in a single fragment, create an | 158 | * Given a buffer that doesn't fit in a single fragment, create an |
| 163 | * scatter/gather structure for delivery to the USB pipe. | 159 | * scatter/gather structure for delivery to the USB pipe. |
| 164 | * | 160 | * |
| @@ -253,15 +249,11 @@ int i1480u_tx_create_n(struct i1480u_tx *wtx, struct sk_buff *skb, | |||
| 253 | /* Now do each remaining fragment */ | 249 | /* Now do each remaining fragment */ |
| 254 | result = -EINVAL; | 250 | result = -EINVAL; |
| 255 | while (pl_size_left > 0) { | 251 | while (pl_size_left > 0) { |
| 256 | d_printf(5, NULL, "ITR HDR: pl_size_left %zu buf_itr %zu\n", | ||
| 257 | pl_size_left, buf_itr - wtx->buf); | ||
| 258 | if (buf_itr + sizeof(*untd_hdr_rst) - wtx->buf | 252 | if (buf_itr + sizeof(*untd_hdr_rst) - wtx->buf |
| 259 | > wtx->buf_size) { | 253 | > wtx->buf_size) { |
| 260 | printk(KERN_ERR "BUG: no space for header\n"); | 254 | printk(KERN_ERR "BUG: no space for header\n"); |
| 261 | goto error_bug; | 255 | goto error_bug; |
| 262 | } | 256 | } |
| 263 | d_printf(5, NULL, "ITR HDR 2: pl_size_left %zu buf_itr %zu\n", | ||
| 264 | pl_size_left, buf_itr - wtx->buf); | ||
| 265 | untd_hdr_rst = buf_itr; | 257 | untd_hdr_rst = buf_itr; |
| 266 | buf_itr += sizeof(*untd_hdr_rst); | 258 | buf_itr += sizeof(*untd_hdr_rst); |
| 267 | if (pl_size_left > i1480u_MAX_PL_SIZE) { | 259 | if (pl_size_left > i1480u_MAX_PL_SIZE) { |
| @@ -271,9 +263,6 @@ int i1480u_tx_create_n(struct i1480u_tx *wtx, struct sk_buff *skb, | |||
| 271 | frg_pl_size = pl_size_left; | 263 | frg_pl_size = pl_size_left; |
| 272 | untd_hdr_set_type(&untd_hdr_rst->hdr, i1480u_PKT_FRAG_LST); | 264 | untd_hdr_set_type(&untd_hdr_rst->hdr, i1480u_PKT_FRAG_LST); |
| 273 | } | 265 | } |
| 274 | d_printf(5, NULL, | ||
| 275 | "ITR PL: pl_size_left %zu buf_itr %zu frg_pl_size %zu\n", | ||
| 276 | pl_size_left, buf_itr - wtx->buf, frg_pl_size); | ||
| 277 | untd_hdr_set_rx_tx(&untd_hdr_rst->hdr, 0); | 266 | untd_hdr_set_rx_tx(&untd_hdr_rst->hdr, 0); |
| 278 | untd_hdr_rst->hdr.len = cpu_to_le16(frg_pl_size); | 267 | untd_hdr_rst->hdr.len = cpu_to_le16(frg_pl_size); |
| 279 | untd_hdr_rst->padding = 0; | 268 | untd_hdr_rst->padding = 0; |
| @@ -286,9 +275,6 @@ int i1480u_tx_create_n(struct i1480u_tx *wtx, struct sk_buff *skb, | |||
| 286 | buf_itr += frg_pl_size; | 275 | buf_itr += frg_pl_size; |
| 287 | pl_itr += frg_pl_size; | 276 | pl_itr += frg_pl_size; |
| 288 | pl_size_left -= frg_pl_size; | 277 | pl_size_left -= frg_pl_size; |
| 289 | d_printf(5, NULL, | ||
| 290 | "ITR PL 2: pl_size_left %zu buf_itr %zu frg_pl_size %zu\n", | ||
| 291 | pl_size_left, buf_itr - wtx->buf, frg_pl_size); | ||
| 292 | } | 278 | } |
| 293 | dev_kfree_skb_irq(skb); | 279 | dev_kfree_skb_irq(skb); |
| 294 | return 0; | 280 | return 0; |
| @@ -308,7 +294,7 @@ error_buf_alloc: | |||
| 308 | } | 294 | } |
| 309 | 295 | ||
| 310 | 296 | ||
| 311 | /** | 297 | /* |
| 312 | * Given a buffer that fits in a single fragment, fill out a @wtx | 298 | * Given a buffer that fits in a single fragment, fill out a @wtx |
| 313 | * struct for transmitting it down the USB pipe. | 299 | * struct for transmitting it down the USB pipe. |
| 314 | * | 300 | * |
| @@ -346,7 +332,7 @@ int i1480u_tx_create_1(struct i1480u_tx *wtx, struct sk_buff *skb, | |||
| 346 | } | 332 | } |
| 347 | 333 | ||
| 348 | 334 | ||
| 349 | /** | 335 | /* |
| 350 | * Given a skb to transmit, massage it to become palatable for the TX pipe | 336 | * Given a skb to transmit, massage it to become palatable for the TX pipe |
| 351 | * | 337 | * |
| 352 | * This will break the buffer in chunks smaller than | 338 | * This will break the buffer in chunks smaller than |
| @@ -425,7 +411,7 @@ error_wtx_alloc: | |||
| 425 | return NULL; | 411 | return NULL; |
| 426 | } | 412 | } |
| 427 | 413 | ||
| 428 | /** | 414 | /* |
| 429 | * Actual fragmentation and transmission of frame | 415 | * Actual fragmentation and transmission of frame |
| 430 | * | 416 | * |
| 431 | * @wlp: WLP substack data structure | 417 | * @wlp: WLP substack data structure |
| @@ -447,20 +433,12 @@ int i1480u_xmit_frame(struct wlp *wlp, struct sk_buff *skb, | |||
| 447 | struct i1480u_tx *wtx; | 433 | struct i1480u_tx *wtx; |
| 448 | struct wlp_tx_hdr *wlp_tx_hdr; | 434 | struct wlp_tx_hdr *wlp_tx_hdr; |
| 449 | static unsigned char dev_bcast[2] = { 0xff, 0xff }; | 435 | static unsigned char dev_bcast[2] = { 0xff, 0xff }; |
| 450 | #if 0 | ||
| 451 | int lockup = 50; | ||
| 452 | #endif | ||
| 453 | 436 | ||
| 454 | d_fnstart(6, dev, "(skb %p (%u), net_dev %p)\n", skb, skb->len, | ||
| 455 | net_dev); | ||
| 456 | BUG_ON(i1480u->wlp.rc == NULL); | 437 | BUG_ON(i1480u->wlp.rc == NULL); |
| 457 | if ((net_dev->flags & IFF_UP) == 0) | 438 | if ((net_dev->flags & IFF_UP) == 0) |
| 458 | goto out; | 439 | goto out; |
| 459 | result = -EBUSY; | 440 | result = -EBUSY; |
| 460 | if (atomic_read(&i1480u->tx_inflight.count) >= i1480u->tx_inflight.max) { | 441 | if (atomic_read(&i1480u->tx_inflight.count) >= i1480u->tx_inflight.max) { |
| 461 | if (d_test(2) && printk_ratelimit()) | ||
| 462 | d_printf(2, dev, "Max frames in flight " | ||
| 463 | "stopping queue.\n"); | ||
| 464 | netif_stop_queue(net_dev); | 442 | netif_stop_queue(net_dev); |
| 465 | goto error_max_inflight; | 443 | goto error_max_inflight; |
| 466 | } | 444 | } |
| @@ -489,21 +467,6 @@ int i1480u_xmit_frame(struct wlp *wlp, struct sk_buff *skb, | |||
| 489 | wlp_tx_hdr_set_delivery_id_type(wlp_tx_hdr, i1480u->options.pca_base_priority); | 467 | wlp_tx_hdr_set_delivery_id_type(wlp_tx_hdr, i1480u->options.pca_base_priority); |
| 490 | } | 468 | } |
| 491 | 469 | ||
| 492 | #if 0 | ||
| 493 | dev_info(dev, "TX delivering skb -> USB, %zu bytes\n", skb->len); | ||
| 494 | dump_bytes(dev, skb->data, skb->len > 72 ? 72 : skb->len); | ||
| 495 | #endif | ||
| 496 | #if 0 | ||
| 497 | /* simulates a device lockup after every lockup# packets */ | ||
| 498 | if (lockup && ((i1480u->stats.tx_packets + 1) % lockup) == 0) { | ||
| 499 | /* Simulate a dropped transmit interrupt */ | ||
| 500 | net_dev->trans_start = jiffies; | ||
| 501 | netif_stop_queue(net_dev); | ||
| 502 | dev_err(dev, "Simulate lockup at %ld\n", jiffies); | ||
| 503 | return result; | ||
| 504 | } | ||
| 505 | #endif | ||
| 506 | |||
| 507 | result = usb_submit_urb(wtx->urb, GFP_ATOMIC); /* Go baby */ | 470 | result = usb_submit_urb(wtx->urb, GFP_ATOMIC); /* Go baby */ |
| 508 | if (result < 0) { | 471 | if (result < 0) { |
| 509 | dev_err(dev, "TX: cannot submit URB: %d\n", result); | 472 | dev_err(dev, "TX: cannot submit URB: %d\n", result); |
| @@ -513,8 +476,6 @@ int i1480u_xmit_frame(struct wlp *wlp, struct sk_buff *skb, | |||
| 513 | } | 476 | } |
| 514 | atomic_inc(&i1480u->tx_inflight.count); | 477 | atomic_inc(&i1480u->tx_inflight.count); |
| 515 | net_dev->trans_start = jiffies; | 478 | net_dev->trans_start = jiffies; |
| 516 | d_fnend(6, dev, "(skb %p (%u), net_dev %p) = %d\n", skb, skb->len, | ||
| 517 | net_dev, result); | ||
| 518 | return result; | 479 | return result; |
| 519 | 480 | ||
| 520 | error_tx_urb_submit: | 481 | error_tx_urb_submit: |
| @@ -522,13 +483,11 @@ error_tx_urb_submit: | |||
| 522 | error_wtx_alloc: | 483 | error_wtx_alloc: |
| 523 | error_max_inflight: | 484 | error_max_inflight: |
| 524 | out: | 485 | out: |
| 525 | d_fnend(6, dev, "(skb %p (%u), net_dev %p) = %d\n", skb, skb->len, | ||
| 526 | net_dev, result); | ||
| 527 | return result; | 486 | return result; |
| 528 | } | 487 | } |
| 529 | 488 | ||
| 530 | 489 | ||
| 531 | /** | 490 | /* |
| 532 | * Transmit an skb Called when an skbuf has to be transmitted | 491 | * Transmit an skb Called when an skbuf has to be transmitted |
| 533 | * | 492 | * |
| 534 | * The skb is first passed to WLP substack to ensure this is a valid | 493 | * The skb is first passed to WLP substack to ensure this is a valid |
| @@ -551,9 +510,6 @@ int i1480u_hard_start_xmit(struct sk_buff *skb, struct net_device *net_dev) | |||
| 551 | struct device *dev = &i1480u->usb_iface->dev; | 510 | struct device *dev = &i1480u->usb_iface->dev; |
| 552 | struct uwb_dev_addr dst; | 511 | struct uwb_dev_addr dst; |
| 553 | 512 | ||
| 554 | d_fnstart(6, dev, "(skb %p (%u), net_dev %p)\n", skb, skb->len, | ||
| 555 | net_dev); | ||
| 556 | BUG_ON(i1480u->wlp.rc == NULL); | ||
| 557 | if ((net_dev->flags & IFF_UP) == 0) | 513 | if ((net_dev->flags & IFF_UP) == 0) |
| 558 | goto error; | 514 | goto error; |
| 559 | result = wlp_prepare_tx_frame(dev, &i1480u->wlp, skb, &dst); | 515 | result = wlp_prepare_tx_frame(dev, &i1480u->wlp, skb, &dst); |
| @@ -562,31 +518,25 @@ int i1480u_hard_start_xmit(struct sk_buff *skb, struct net_device *net_dev) | |||
| 562 | "Dropping packet.\n", result); | 518 | "Dropping packet.\n", result); |
| 563 | goto error; | 519 | goto error; |
| 564 | } else if (result == 1) { | 520 | } else if (result == 1) { |
| 565 | d_printf(6, dev, "WLP will transmit frame. \n"); | ||
| 566 | /* trans_start time will be set when WLP actually transmits | 521 | /* trans_start time will be set when WLP actually transmits |
| 567 | * the frame */ | 522 | * the frame */ |
| 568 | goto out; | 523 | goto out; |
| 569 | } | 524 | } |
| 570 | d_printf(6, dev, "Transmitting frame. \n"); | ||
| 571 | result = i1480u_xmit_frame(&i1480u->wlp, skb, &dst); | 525 | result = i1480u_xmit_frame(&i1480u->wlp, skb, &dst); |
| 572 | if (result < 0) { | 526 | if (result < 0) { |
| 573 | dev_err(dev, "Frame TX failed (%d).\n", result); | 527 | dev_err(dev, "Frame TX failed (%d).\n", result); |
| 574 | goto error; | 528 | goto error; |
| 575 | } | 529 | } |
| 576 | d_fnend(6, dev, "(skb %p (%u), net_dev %p) = %d\n", skb, skb->len, | ||
| 577 | net_dev, result); | ||
| 578 | return NETDEV_TX_OK; | 530 | return NETDEV_TX_OK; |
| 579 | error: | 531 | error: |
| 580 | dev_kfree_skb_any(skb); | 532 | dev_kfree_skb_any(skb); |
| 581 | i1480u->stats.tx_dropped++; | 533 | i1480u->stats.tx_dropped++; |
| 582 | out: | 534 | out: |
| 583 | d_fnend(6, dev, "(skb %p (%u), net_dev %p) = %d\n", skb, skb->len, | ||
| 584 | net_dev, result); | ||
| 585 | return NETDEV_TX_OK; | 535 | return NETDEV_TX_OK; |
| 586 | } | 536 | } |
| 587 | 537 | ||
| 588 | 538 | ||
| 589 | /** | 539 | /* |
| 590 | * Called when a pkt transmission doesn't complete in a reasonable period | 540 | * Called when a pkt transmission doesn't complete in a reasonable period |
| 591 | * Device reset may sleep - do it outside of interrupt context (delayed) | 541 | * Device reset may sleep - do it outside of interrupt context (delayed) |
| 592 | */ | 542 | */ |
diff --git a/drivers/uwb/ie-rcv.c b/drivers/uwb/ie-rcv.c new file mode 100644 index 00000000000..917e6d78a79 --- /dev/null +++ b/drivers/uwb/ie-rcv.c | |||
| @@ -0,0 +1,55 @@ | |||
| 1 | /* | ||
| 2 | * Ultra Wide Band | ||
| 3 | * IE Received notification handling. | ||
| 4 | * | ||
| 5 | * Copyright (C) 2008 Cambridge Silicon Radio Ltd. | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU General Public License version | ||
| 9 | * 2 as published by the Free Software Foundation. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <linux/errno.h> | ||
| 21 | #include <linux/module.h> | ||
| 22 | #include <linux/device.h> | ||
| 23 | #include <linux/bitmap.h> | ||
| 24 | #include "uwb-internal.h" | ||
| 25 | |||
| 26 | /* | ||
| 27 | * Process an incoming IE Received notification. | ||
| 28 | */ | ||
| 29 | int uwbd_evt_handle_rc_ie_rcv(struct uwb_event *evt) | ||
| 30 | { | ||
| 31 | int result = -EINVAL; | ||
| 32 | struct device *dev = &evt->rc->uwb_dev.dev; | ||
| 33 | struct uwb_rc_evt_ie_rcv *iercv; | ||
| 34 | size_t iesize; | ||
| 35 | |||
| 36 | /* Is there enough data to decode it? */ | ||
| 37 | if (evt->notif.size < sizeof(*iercv)) { | ||
| 38 | dev_err(dev, "IE Received notification: Not enough data to " | ||
| 39 | "decode (%zu vs %zu bytes needed)\n", | ||
| 40 | evt->notif.size, sizeof(*iercv)); | ||
| 41 | goto error; | ||
| 42 | } | ||
| 43 | iercv = container_of(evt->notif.rceb, struct uwb_rc_evt_ie_rcv, rceb); | ||
| 44 | iesize = le16_to_cpu(iercv->wIELength); | ||
| 45 | |||
| 46 | dev_dbg(dev, "IE received, element ID=%d\n", iercv->IEData[0]); | ||
| 47 | |||
| 48 | if (iercv->IEData[0] == UWB_RELINQUISH_REQUEST_IE) { | ||
| 49 | dev_warn(dev, "unhandled Relinquish Request IE\n"); | ||
| 50 | } | ||
| 51 | |||
| 52 | return 0; | ||
| 53 | error: | ||
| 54 | return result; | ||
| 55 | } | ||
diff --git a/drivers/uwb/ie.c b/drivers/uwb/ie.c index cf6f3d152b9..ab976686175 100644 --- a/drivers/uwb/ie.c +++ b/drivers/uwb/ie.c | |||
| @@ -25,8 +25,6 @@ | |||
| 25 | */ | 25 | */ |
| 26 | 26 | ||
| 27 | #include "uwb-internal.h" | 27 | #include "uwb-internal.h" |
| 28 | #define D_LOCAL 0 | ||
| 29 | #include <linux/uwb/debug.h> | ||
| 30 | 28 | ||
| 31 | /** | 29 | /** |
| 32 | * uwb_ie_next - get the next IE in a buffer | 30 | * uwb_ie_next - get the next IE in a buffer |
| @@ -61,6 +59,42 @@ struct uwb_ie_hdr *uwb_ie_next(void **ptr, size_t *len) | |||
| 61 | EXPORT_SYMBOL_GPL(uwb_ie_next); | 59 | EXPORT_SYMBOL_GPL(uwb_ie_next); |
| 62 | 60 | ||
| 63 | /** | 61 | /** |
| 62 | * uwb_ie_dump_hex - print IEs to a character buffer | ||
| 63 | * @ies: the IEs to print. | ||
| 64 | * @len: length of all the IEs. | ||
| 65 | * @buf: the destination buffer. | ||
| 66 | * @size: size of @buf. | ||
| 67 | * | ||
| 68 | * Returns the number of characters written. | ||
| 69 | */ | ||
| 70 | int uwb_ie_dump_hex(const struct uwb_ie_hdr *ies, size_t len, | ||
| 71 | char *buf, size_t size) | ||
| 72 | { | ||
| 73 | void *ptr; | ||
| 74 | const struct uwb_ie_hdr *ie; | ||
| 75 | int r = 0; | ||
| 76 | u8 *d; | ||
| 77 | |||
| 78 | ptr = (void *)ies; | ||
| 79 | for (;;) { | ||
| 80 | ie = uwb_ie_next(&ptr, &len); | ||
| 81 | if (!ie) | ||
| 82 | break; | ||
| 83 | |||
| 84 | r += scnprintf(buf + r, size - r, "%02x %02x", | ||
| 85 | (unsigned)ie->element_id, | ||
| 86 | (unsigned)ie->length); | ||
| 87 | d = (uint8_t *)ie + sizeof(struct uwb_ie_hdr); | ||
| 88 | while (d != ptr && r < size) | ||
| 89 | r += scnprintf(buf + r, size - r, " %02x", (unsigned)*d++); | ||
| 90 | if (r < size) | ||
| 91 | buf[r++] = '\n'; | ||
| 92 | }; | ||
| 93 | |||
| 94 | return r; | ||
| 95 | } | ||
| 96 | |||
| 97 | /** | ||
| 64 | * Get the IEs that a radio controller is sending in its beacon | 98 | * Get the IEs that a radio controller is sending in its beacon |
| 65 | * | 99 | * |
| 66 | * @uwb_rc: UWB Radio Controller | 100 | * @uwb_rc: UWB Radio Controller |
| @@ -70,6 +104,7 @@ EXPORT_SYMBOL_GPL(uwb_ie_next); | |||
| 70 | * anything. Once done with the iedata buffer, call | 104 | * anything. Once done with the iedata buffer, call |
| 71 | * uwb_rc_ie_release(iedata). Don't call kfree on it. | 105 | * uwb_rc_ie_release(iedata). Don't call kfree on it. |
| 72 | */ | 106 | */ |
| 107 | static | ||
| 73 | ssize_t uwb_rc_get_ie(struct uwb_rc *uwb_rc, struct uwb_rc_evt_get_ie **pget_ie) | 108 | ssize_t uwb_rc_get_ie(struct uwb_rc *uwb_rc, struct uwb_rc_evt_get_ie **pget_ie) |
| 74 | { | 109 | { |
| 75 | ssize_t result; | 110 | ssize_t result; |
| @@ -78,148 +113,35 @@ ssize_t uwb_rc_get_ie(struct uwb_rc *uwb_rc, struct uwb_rc_evt_get_ie **pget_ie) | |||
| 78 | struct uwb_rceb *reply = NULL; | 113 | struct uwb_rceb *reply = NULL; |
| 79 | struct uwb_rc_evt_get_ie *get_ie; | 114 | struct uwb_rc_evt_get_ie *get_ie; |
| 80 | 115 | ||
| 81 | d_fnstart(3, dev, "(%p, %p)\n", uwb_rc, pget_ie); | ||
| 82 | result = -ENOMEM; | ||
| 83 | cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); | 116 | cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); |
| 84 | if (cmd == NULL) | 117 | if (cmd == NULL) |
| 85 | goto error_kzalloc; | 118 | return -ENOMEM; |
| 119 | |||
| 86 | cmd->bCommandType = UWB_RC_CET_GENERAL; | 120 | cmd->bCommandType = UWB_RC_CET_GENERAL; |
| 87 | cmd->wCommand = cpu_to_le16(UWB_RC_CMD_GET_IE); | 121 | cmd->wCommand = cpu_to_le16(UWB_RC_CMD_GET_IE); |
| 88 | result = uwb_rc_vcmd(uwb_rc, "GET_IE", cmd, sizeof(*cmd), | 122 | result = uwb_rc_vcmd(uwb_rc, "GET_IE", cmd, sizeof(*cmd), |
| 89 | UWB_RC_CET_GENERAL, UWB_RC_CMD_GET_IE, | 123 | UWB_RC_CET_GENERAL, UWB_RC_CMD_GET_IE, |
| 90 | &reply); | 124 | &reply); |
| 125 | kfree(cmd); | ||
| 91 | if (result < 0) | 126 | if (result < 0) |
| 92 | goto error_cmd; | 127 | return result; |
| 128 | |||
| 93 | get_ie = container_of(reply, struct uwb_rc_evt_get_ie, rceb); | 129 | get_ie = container_of(reply, struct uwb_rc_evt_get_ie, rceb); |
| 94 | if (result < sizeof(*get_ie)) { | 130 | if (result < sizeof(*get_ie)) { |
| 95 | dev_err(dev, "not enough data returned for decoding GET IE " | 131 | dev_err(dev, "not enough data returned for decoding GET IE " |
| 96 | "(%zu bytes received vs %zu needed)\n", | 132 | "(%zu bytes received vs %zu needed)\n", |
| 97 | result, sizeof(*get_ie)); | 133 | result, sizeof(*get_ie)); |
| 98 | result = -EINVAL; | 134 | return -EINVAL; |
| 99 | } else if (result < sizeof(*get_ie) + le16_to_cpu(get_ie->wIELength)) { | 135 | } else if (result < sizeof(*get_ie) + le16_to_cpu(get_ie->wIELength)) { |
| 100 | dev_err(dev, "not enough data returned for decoding GET IE " | 136 | dev_err(dev, "not enough data returned for decoding GET IE " |
| 101 | "payload (%zu bytes received vs %zu needed)\n", result, | 137 | "payload (%zu bytes received vs %zu needed)\n", result, |
| 102 | sizeof(*get_ie) + le16_to_cpu(get_ie->wIELength)); | 138 | sizeof(*get_ie) + le16_to_cpu(get_ie->wIELength)); |
| 103 | result = -EINVAL; | ||
| 104 | } else | ||
| 105 | *pget_ie = get_ie; | ||
| 106 | error_cmd: | ||
| 107 | kfree(cmd); | ||
| 108 | error_kzalloc: | ||
| 109 | d_fnend(3, dev, "(%p, %p) = %d\n", uwb_rc, pget_ie, (int)result); | ||
| 110 | return result; | ||
| 111 | } | ||
| 112 | EXPORT_SYMBOL_GPL(uwb_rc_get_ie); | ||
| 113 | |||
| 114 | |||
| 115 | /* | ||
| 116 | * Given a pointer to an IE, print it in ASCII/hex followed by a new line | ||
| 117 | * | ||
| 118 | * @ie_hdr: pointer to the IE header. Length is in there, and it is | ||
| 119 | * guaranteed that the ie_hdr->length bytes following it are | ||
| 120 | * safely accesible. | ||
| 121 | * | ||
| 122 | * @_data: context data passed from uwb_ie_for_each(), an struct output_ctx | ||
| 123 | */ | ||
| 124 | int uwb_ie_dump_hex(struct uwb_dev *uwb_dev, const struct uwb_ie_hdr *ie_hdr, | ||
| 125 | size_t offset, void *_ctx) | ||
| 126 | { | ||
| 127 | struct uwb_buf_ctx *ctx = _ctx; | ||
| 128 | const u8 *pl = (void *)(ie_hdr + 1); | ||
| 129 | u8 pl_itr; | ||
| 130 | |||
| 131 | ctx->bytes += scnprintf(ctx->buf + ctx->bytes, ctx->size - ctx->bytes, | ||
| 132 | "%02x %02x ", (unsigned) ie_hdr->element_id, | ||
| 133 | (unsigned) ie_hdr->length); | ||
| 134 | pl_itr = 0; | ||
| 135 | while (pl_itr < ie_hdr->length && ctx->bytes < ctx->size) | ||
| 136 | ctx->bytes += scnprintf(ctx->buf + ctx->bytes, | ||
| 137 | ctx->size - ctx->bytes, | ||
| 138 | "%02x ", (unsigned) pl[pl_itr++]); | ||
| 139 | if (ctx->bytes < ctx->size) | ||
| 140 | ctx->buf[ctx->bytes++] = '\n'; | ||
| 141 | return 0; | ||
| 142 | } | ||
| 143 | EXPORT_SYMBOL_GPL(uwb_ie_dump_hex); | ||
| 144 | |||
| 145 | |||
| 146 | /** | ||
| 147 | * Verify that a pointer in a buffer points to valid IE | ||
| 148 | * | ||
| 149 | * @start: pointer to start of buffer in which IE appears | ||
| 150 | * @itr: pointer to IE inside buffer that will be verified | ||
| 151 | * @top: pointer to end of buffer | ||
| 152 | * | ||
| 153 | * @returns: 0 if IE is valid, <0 otherwise | ||
| 154 | * | ||
| 155 | * Verification involves checking that the buffer can contain a | ||
| 156 | * header and the amount of data reported in the IE header can be found in | ||
| 157 | * the buffer. | ||
| 158 | */ | ||
| 159 | static | ||
| 160 | int uwb_rc_ie_verify(struct uwb_dev *uwb_dev, const void *start, | ||
| 161 | const void *itr, const void *top) | ||
| 162 | { | ||
| 163 | struct device *dev = &uwb_dev->dev; | ||
| 164 | const struct uwb_ie_hdr *ie_hdr; | ||
| 165 | |||
| 166 | if (top - itr < sizeof(*ie_hdr)) { | ||
| 167 | dev_err(dev, "Bad IE: no data to decode header " | ||
| 168 | "(%zu bytes left vs %zu needed) at offset %zu\n", | ||
| 169 | top - itr, sizeof(*ie_hdr), itr - start); | ||
| 170 | return -EINVAL; | ||
| 171 | } | ||
| 172 | ie_hdr = itr; | ||
| 173 | itr += sizeof(*ie_hdr); | ||
| 174 | if (top - itr < ie_hdr->length) { | ||
| 175 | dev_err(dev, "Bad IE: not enough data for payload " | ||
| 176 | "(%zu bytes left vs %zu needed) at offset %zu\n", | ||
| 177 | top - itr, (size_t)ie_hdr->length, | ||
| 178 | (void *)ie_hdr - start); | ||
| 179 | return -EINVAL; | 139 | return -EINVAL; |
| 180 | } | 140 | } |
| 181 | return 0; | ||
| 182 | } | ||
| 183 | 141 | ||
| 184 | 142 | *pget_ie = get_ie; | |
| 185 | /** | ||
| 186 | * Walk a buffer filled with consecutive IE's a buffer | ||
| 187 | * | ||
| 188 | * @uwb_dev: UWB device this IEs belong to (for err messages mainly) | ||
| 189 | * | ||
| 190 | * @fn: function to call with each IE; if it returns 0, we keep | ||
| 191 | * traversing the buffer. If it returns !0, we'll stop and return | ||
| 192 | * that value. | ||
| 193 | * | ||
| 194 | * @data: pointer passed to @fn | ||
| 195 | * | ||
| 196 | * @buf: buffer where the consecutive IEs are located | ||
| 197 | * | ||
| 198 | * @size: size of @buf | ||
| 199 | * | ||
| 200 | * Each IE is checked for basic correctness (there is space left for | ||
| 201 | * the header and the payload). If that test is failed, we stop | ||
| 202 | * processing. For every good IE, @fn is called. | ||
| 203 | */ | ||
| 204 | ssize_t uwb_ie_for_each(struct uwb_dev *uwb_dev, uwb_ie_f fn, void *data, | ||
| 205 | const void *buf, size_t size) | ||
| 206 | { | ||
| 207 | ssize_t result = 0; | ||
| 208 | const struct uwb_ie_hdr *ie_hdr; | ||
| 209 | const void *itr = buf, *top = itr + size; | ||
| 210 | |||
| 211 | while (itr < top) { | ||
| 212 | if (uwb_rc_ie_verify(uwb_dev, buf, itr, top) != 0) | ||
| 213 | break; | ||
| 214 | ie_hdr = itr; | ||
| 215 | itr += sizeof(*ie_hdr) + ie_hdr->length; | ||
| 216 | result = fn(uwb_dev, ie_hdr, itr - buf, data); | ||
| 217 | if (result != 0) | ||
| 218 | break; | ||
| 219 | } | ||
| 220 | return result; | 143 | return result; |
| 221 | } | 144 | } |
| 222 | EXPORT_SYMBOL_GPL(uwb_ie_for_each); | ||
| 223 | 145 | ||
| 224 | 146 | ||
| 225 | /** | 147 | /** |
| @@ -256,70 +178,6 @@ error_cmd: | |||
| 256 | return result; | 178 | return result; |
| 257 | } | 179 | } |
| 258 | 180 | ||
| 259 | /** | ||
| 260 | * Determine by IE id if IE is host settable | ||
| 261 | * WUSB 1.0 [8.6.2.8 Table 8.85] | ||
| 262 | * | ||
| 263 | * EXCEPTION: | ||
| 264 | * All but UWB_IE_WLP appears in Table 8.85 from WUSB 1.0. Setting this IE | ||
| 265 | * is required for the WLP substack to perform association with its WSS so | ||
| 266 | * we hope that the WUSB spec will be changed to reflect this. | ||
| 267 | */ | ||
| 268 | static | ||
| 269 | int uwb_rc_ie_is_host_settable(enum uwb_ie element_id) | ||
| 270 | { | ||
| 271 | if (element_id == UWB_PCA_AVAILABILITY || | ||
| 272 | element_id == UWB_BP_SWITCH_IE || | ||
| 273 | element_id == UWB_MAC_CAPABILITIES_IE || | ||
| 274 | element_id == UWB_PHY_CAPABILITIES_IE || | ||
| 275 | element_id == UWB_APP_SPEC_PROBE_IE || | ||
| 276 | element_id == UWB_IDENTIFICATION_IE || | ||
| 277 | element_id == UWB_MASTER_KEY_ID_IE || | ||
| 278 | element_id == UWB_IE_WLP || | ||
| 279 | element_id == UWB_APP_SPEC_IE) | ||
| 280 | return 1; | ||
| 281 | return 0; | ||
| 282 | } | ||
| 283 | |||
| 284 | |||
| 285 | /** | ||
| 286 | * Extract Host Settable IEs from IE | ||
| 287 | * | ||
| 288 | * @ie_data: pointer to buffer containing all IEs | ||
| 289 | * @size: size of buffer | ||
| 290 | * | ||
| 291 | * @returns: length of buffer that only includes host settable IEs | ||
| 292 | * | ||
| 293 | * Given a buffer of IEs we move all Host Settable IEs to front of buffer | ||
| 294 | * by overwriting the IEs that are not Host Settable. | ||
| 295 | * Buffer length is adjusted accordingly. | ||
| 296 | */ | ||
| 297 | static | ||
| 298 | ssize_t uwb_rc_parse_host_settable_ie(struct uwb_dev *uwb_dev, | ||
| 299 | void *ie_data, size_t size) | ||
| 300 | { | ||
| 301 | size_t new_len = size; | ||
| 302 | struct uwb_ie_hdr *ie_hdr; | ||
| 303 | size_t ie_length; | ||
| 304 | void *itr = ie_data, *top = itr + size; | ||
| 305 | |||
| 306 | while (itr < top) { | ||
| 307 | if (uwb_rc_ie_verify(uwb_dev, ie_data, itr, top) != 0) | ||
| 308 | break; | ||
| 309 | ie_hdr = itr; | ||
| 310 | ie_length = sizeof(*ie_hdr) + ie_hdr->length; | ||
| 311 | if (uwb_rc_ie_is_host_settable(ie_hdr->element_id)) { | ||
| 312 | itr += ie_length; | ||
| 313 | } else { | ||
| 314 | memmove(itr, itr + ie_length, top - (itr + ie_length)); | ||
| 315 | new_len -= ie_length; | ||
| 316 | top -= ie_length; | ||
| 317 | } | ||
| 318 | } | ||
| 319 | return new_len; | ||
| 320 | } | ||
| 321 | |||
| 322 | |||
| 323 | /* Cleanup the whole IE management subsystem */ | 181 | /* Cleanup the whole IE management subsystem */ |
| 324 | void uwb_rc_ie_init(struct uwb_rc *uwb_rc) | 182 | void uwb_rc_ie_init(struct uwb_rc *uwb_rc) |
| 325 | { | 183 | { |
| @@ -328,49 +186,34 @@ void uwb_rc_ie_init(struct uwb_rc *uwb_rc) | |||
| 328 | 186 | ||
| 329 | 187 | ||
| 330 | /** | 188 | /** |
| 331 | * Set up cache for host settable IEs currently being transmitted | 189 | * uwb_rc_ie_setup - setup a radio controller's IE manager |
| 190 | * @uwb_rc: the radio controller. | ||
| 332 | * | 191 | * |
| 333 | * First we just call GET-IE to get the current IEs being transmitted | 192 | * The current set of IEs are obtained from the hardware with a GET-IE |
| 334 | * (or we workaround and pretend we did) and (because the format is | 193 | * command (since the radio controller is not yet beaconing this will |
| 335 | * the same) reuse that as the IE cache (with the command prefix, as | 194 | * be just the hardware's MAC and PHY Capability IEs). |
| 336 | * explained in 'struct uwb_rc'). | ||
| 337 | * | 195 | * |
| 338 | * @returns: size of cache created | 196 | * Returns 0 on success; -ve on an error. |
| 339 | */ | 197 | */ |
| 340 | ssize_t uwb_rc_ie_setup(struct uwb_rc *uwb_rc) | 198 | int uwb_rc_ie_setup(struct uwb_rc *uwb_rc) |
| 341 | { | 199 | { |
| 342 | struct device *dev = &uwb_rc->uwb_dev.dev; | 200 | struct uwb_rc_evt_get_ie *ie_info = NULL; |
| 343 | ssize_t result; | 201 | int capacity; |
| 344 | size_t capacity; | 202 | |
| 345 | struct uwb_rc_evt_get_ie *ie_info; | 203 | capacity = uwb_rc_get_ie(uwb_rc, &ie_info); |
| 204 | if (capacity < 0) | ||
| 205 | return capacity; | ||
| 346 | 206 | ||
| 347 | d_fnstart(3, dev, "(%p)\n", uwb_rc); | ||
| 348 | mutex_lock(&uwb_rc->ies_mutex); | 207 | mutex_lock(&uwb_rc->ies_mutex); |
| 349 | result = uwb_rc_get_ie(uwb_rc, &ie_info); | 208 | |
| 350 | if (result < 0) | 209 | uwb_rc->ies = (struct uwb_rc_cmd_set_ie *)ie_info; |
| 351 | goto error_get_ie; | ||
| 352 | capacity = result; | ||
| 353 | d_printf(5, dev, "Got IEs %zu bytes (%zu long at %p)\n", result, | ||
| 354 | (size_t)le16_to_cpu(ie_info->wIELength), ie_info); | ||
| 355 | |||
| 356 | /* Remove IEs that host should not set. */ | ||
| 357 | result = uwb_rc_parse_host_settable_ie(&uwb_rc->uwb_dev, | ||
| 358 | ie_info->IEData, le16_to_cpu(ie_info->wIELength)); | ||
| 359 | if (result < 0) | ||
| 360 | goto error_parse; | ||
| 361 | d_printf(5, dev, "purged non-settable IEs to %zu bytes\n", result); | ||
| 362 | uwb_rc->ies = (void *) ie_info; | ||
| 363 | uwb_rc->ies->rccb.bCommandType = UWB_RC_CET_GENERAL; | 210 | uwb_rc->ies->rccb.bCommandType = UWB_RC_CET_GENERAL; |
| 364 | uwb_rc->ies->rccb.wCommand = cpu_to_le16(UWB_RC_CMD_SET_IE); | 211 | uwb_rc->ies->rccb.wCommand = cpu_to_le16(UWB_RC_CMD_SET_IE); |
| 365 | uwb_rc->ies_capacity = capacity; | 212 | uwb_rc->ies_capacity = capacity; |
| 366 | d_printf(5, dev, "IE cache at %p %zu bytes, %zu capacity\n", | 213 | |
| 367 | ie_info, result, capacity); | ||
| 368 | result = 0; | ||
| 369 | error_parse: | ||
| 370 | error_get_ie: | ||
| 371 | mutex_unlock(&uwb_rc->ies_mutex); | 214 | mutex_unlock(&uwb_rc->ies_mutex); |
| 372 | d_fnend(3, dev, "(%p) = %zu\n", uwb_rc, result); | 215 | |
| 373 | return result; | 216 | return 0; |
| 374 | } | 217 | } |
| 375 | 218 | ||
| 376 | 219 | ||
| @@ -383,26 +226,47 @@ void uwb_rc_ie_release(struct uwb_rc *uwb_rc) | |||
| 383 | } | 226 | } |
| 384 | 227 | ||
| 385 | 228 | ||
| 386 | static | 229 | static int uwb_rc_ie_add_one(struct uwb_rc *rc, const struct uwb_ie_hdr *new_ie) |
| 387 | int __acc_size(struct uwb_dev *uwb_dev, const struct uwb_ie_hdr *ie_hdr, | ||
| 388 | size_t offset, void *_ctx) | ||
| 389 | { | 230 | { |
| 390 | size_t *acc_size = _ctx; | 231 | struct uwb_rc_cmd_set_ie *new_ies; |
| 391 | *acc_size += sizeof(*ie_hdr) + ie_hdr->length; | 232 | void *ptr, *prev_ie; |
| 392 | d_printf(6, &uwb_dev->dev, "new acc size %zu\n", *acc_size); | 233 | struct uwb_ie_hdr *ie; |
| 234 | size_t length, new_ie_len, new_capacity, size, prev_size; | ||
| 235 | |||
| 236 | length = le16_to_cpu(rc->ies->wIELength); | ||
| 237 | new_ie_len = sizeof(struct uwb_ie_hdr) + new_ie->length; | ||
| 238 | new_capacity = sizeof(struct uwb_rc_cmd_set_ie) + length + new_ie_len; | ||
| 239 | |||
| 240 | if (new_capacity > rc->ies_capacity) { | ||
| 241 | new_ies = krealloc(rc->ies, new_capacity, GFP_KERNEL); | ||
| 242 | if (!new_ies) | ||
| 243 | return -ENOMEM; | ||
| 244 | rc->ies = new_ies; | ||
| 245 | } | ||
| 246 | |||
| 247 | ptr = rc->ies->IEData; | ||
| 248 | size = length; | ||
| 249 | for (;;) { | ||
| 250 | prev_ie = ptr; | ||
| 251 | prev_size = size; | ||
| 252 | ie = uwb_ie_next(&ptr, &size); | ||
| 253 | if (!ie || ie->element_id > new_ie->element_id) | ||
| 254 | break; | ||
| 255 | } | ||
| 256 | |||
| 257 | memmove(prev_ie + new_ie_len, prev_ie, prev_size); | ||
| 258 | memcpy(prev_ie, new_ie, new_ie_len); | ||
| 259 | rc->ies->wIELength = cpu_to_le16(length + new_ie_len); | ||
| 260 | |||
| 393 | return 0; | 261 | return 0; |
| 394 | } | 262 | } |
| 395 | 263 | ||
| 396 | |||
| 397 | /** | 264 | /** |
| 398 | * Add a new IE to IEs currently being transmitted by device | 265 | * uwb_rc_ie_add - add new IEs to the radio controller's beacon |
| 399 | * | 266 | * @uwb_rc: the radio controller. |
| 400 | * @ies: the buffer containing the new IE or IEs to be added to | 267 | * @ies: the buffer containing the new IE or IEs to be added to |
| 401 | * the device's beacon. The buffer will be verified for | 268 | * the device's beacon. |
| 402 | * consistence (meaning the headers should be right) and | 269 | * @size: length of all the IEs. |
| 403 | * consistent with the buffer size. | ||
| 404 | * @size: size of @ies (in bytes, total buffer size) | ||
| 405 | * @returns: 0 if ok, <0 errno code on error | ||
| 406 | * | 270 | * |
| 407 | * According to WHCI 0.95 [4.13.6] the driver will only receive the RCEB | 271 | * According to WHCI 0.95 [4.13.6] the driver will only receive the RCEB |
| 408 | * after the device sent the first beacon that includes the IEs specified | 272 | * after the device sent the first beacon that includes the IEs specified |
| @@ -411,66 +275,40 @@ int __acc_size(struct uwb_dev *uwb_dev, const struct uwb_ie_hdr *ie_hdr, | |||
| 411 | * we start beaconing. | 275 | * we start beaconing. |
| 412 | * | 276 | * |
| 413 | * Setting an IE on the device will overwrite all current IEs in device. So | 277 | * Setting an IE on the device will overwrite all current IEs in device. So |
| 414 | * we take the current IEs being transmitted by the device, append the | 278 | * we take the current IEs being transmitted by the device, insert the |
| 415 | * new one, and call SET IE with all the IEs needed. | 279 | * new one, and call SET IE with all the IEs needed. |
| 416 | * | 280 | * |
| 417 | * The local IE cache will only be updated with the new IE if SET IE | 281 | * Returns 0 on success; or -ENOMEM. |
| 418 | * completed successfully. | ||
| 419 | */ | 282 | */ |
| 420 | int uwb_rc_ie_add(struct uwb_rc *uwb_rc, | 283 | int uwb_rc_ie_add(struct uwb_rc *uwb_rc, |
| 421 | const struct uwb_ie_hdr *ies, size_t size) | 284 | const struct uwb_ie_hdr *ies, size_t size) |
| 422 | { | 285 | { |
| 423 | int result = 0; | 286 | int result = 0; |
| 424 | struct device *dev = &uwb_rc->uwb_dev.dev; | 287 | void *ptr; |
| 425 | struct uwb_rc_cmd_set_ie *new_ies; | 288 | const struct uwb_ie_hdr *ie; |
| 426 | size_t ies_size, total_size, acc_size = 0; | 289 | |
| 427 | |||
| 428 | if (uwb_rc->ies == NULL) | ||
| 429 | return -ESHUTDOWN; | ||
| 430 | uwb_ie_for_each(&uwb_rc->uwb_dev, __acc_size, &acc_size, ies, size); | ||
| 431 | if (acc_size != size) { | ||
| 432 | dev_err(dev, "BUG: bad IEs, misconstructed headers " | ||
| 433 | "[%zu bytes reported vs %zu calculated]\n", | ||
| 434 | size, acc_size); | ||
| 435 | WARN_ON(1); | ||
| 436 | return -EINVAL; | ||
| 437 | } | ||
| 438 | mutex_lock(&uwb_rc->ies_mutex); | 290 | mutex_lock(&uwb_rc->ies_mutex); |
| 439 | ies_size = le16_to_cpu(uwb_rc->ies->wIELength); | 291 | |
| 440 | total_size = sizeof(*uwb_rc->ies) + ies_size; | 292 | ptr = (void *)ies; |
| 441 | if (total_size + size > uwb_rc->ies_capacity) { | 293 | for (;;) { |
| 442 | d_printf(4, dev, "Reallocating IE cache from %p capacity %zu " | 294 | ie = uwb_ie_next(&ptr, &size); |
| 443 | "to capacity %zu\n", uwb_rc->ies, uwb_rc->ies_capacity, | 295 | if (!ie) |
| 444 | total_size + size); | 296 | break; |
| 445 | new_ies = kzalloc(total_size + size, GFP_KERNEL); | 297 | |
| 446 | if (new_ies == NULL) { | 298 | result = uwb_rc_ie_add_one(uwb_rc, ie); |
| 447 | dev_err(dev, "No memory for adding new IE\n"); | 299 | if (result < 0) |
| 448 | result = -ENOMEM; | 300 | break; |
| 449 | goto error_alloc; | ||
| 450 | } | ||
| 451 | memcpy(new_ies, uwb_rc->ies, total_size); | ||
| 452 | uwb_rc->ies_capacity = total_size + size; | ||
| 453 | kfree(uwb_rc->ies); | ||
| 454 | uwb_rc->ies = new_ies; | ||
| 455 | d_printf(4, dev, "New IE cache at %p capacity %zu\n", | ||
| 456 | uwb_rc->ies, uwb_rc->ies_capacity); | ||
| 457 | } | 301 | } |
| 458 | memcpy((void *)uwb_rc->ies + total_size, ies, size); | 302 | if (result >= 0) { |
| 459 | uwb_rc->ies->wIELength = cpu_to_le16(ies_size + size); | 303 | if (size == 0) { |
| 460 | if (uwb_rc->beaconing != -1) { | 304 | if (uwb_rc->beaconing != -1) |
| 461 | result = uwb_rc_set_ie(uwb_rc, uwb_rc->ies); | 305 | result = uwb_rc_set_ie(uwb_rc, uwb_rc->ies); |
| 462 | if (result < 0) { | ||
| 463 | dev_err(dev, "Cannot set new IE on device: %d\n", | ||
| 464 | result); | ||
| 465 | uwb_rc->ies->wIELength = cpu_to_le16(ies_size); | ||
| 466 | } else | 306 | } else |
| 467 | result = 0; | 307 | result = -EINVAL; |
| 468 | } | 308 | } |
| 469 | d_printf(4, dev, "IEs now occupy %hu bytes of %zu capacity at %p\n", | 309 | |
| 470 | le16_to_cpu(uwb_rc->ies->wIELength), uwb_rc->ies_capacity, | ||
| 471 | uwb_rc->ies); | ||
| 472 | error_alloc: | ||
| 473 | mutex_unlock(&uwb_rc->ies_mutex); | 310 | mutex_unlock(&uwb_rc->ies_mutex); |
| 311 | |||
| 474 | return result; | 312 | return result; |
| 475 | } | 313 | } |
| 476 | EXPORT_SYMBOL_GPL(uwb_rc_ie_add); | 314 | EXPORT_SYMBOL_GPL(uwb_rc_ie_add); |
| @@ -489,53 +327,52 @@ EXPORT_SYMBOL_GPL(uwb_rc_ie_add); | |||
| 489 | * beacon. We don't reallocate, we just mark the size smaller. | 327 | * beacon. We don't reallocate, we just mark the size smaller. |
| 490 | */ | 328 | */ |
| 491 | static | 329 | static |
| 492 | int uwb_rc_ie_cache_rm(struct uwb_rc *uwb_rc, enum uwb_ie to_remove) | 330 | void uwb_rc_ie_cache_rm(struct uwb_rc *uwb_rc, enum uwb_ie to_remove) |
| 493 | { | 331 | { |
| 494 | struct uwb_ie_hdr *ie_hdr; | 332 | struct uwb_ie_hdr *ie; |
| 495 | size_t new_len = le16_to_cpu(uwb_rc->ies->wIELength); | 333 | size_t len = le16_to_cpu(uwb_rc->ies->wIELength); |
| 496 | void *itr = uwb_rc->ies->IEData; | 334 | void *ptr; |
| 497 | void *top = itr + new_len; | 335 | size_t size; |
| 498 | 336 | ||
| 499 | while (itr < top) { | 337 | ptr = uwb_rc->ies->IEData; |
| 500 | ie_hdr = itr; | 338 | size = len; |
| 501 | if (ie_hdr->element_id != to_remove) { | 339 | for (;;) { |
| 502 | itr += sizeof(*ie_hdr) + ie_hdr->length; | 340 | ie = uwb_ie_next(&ptr, &size); |
| 503 | } else { | 341 | if (!ie) |
| 504 | int ie_length; | 342 | break; |
| 505 | ie_length = sizeof(*ie_hdr) + ie_hdr->length; | 343 | if (ie->element_id == to_remove) { |
| 506 | if (top - itr != ie_length) | 344 | len -= sizeof(struct uwb_ie_hdr) + ie->length; |
| 507 | memmove(itr, itr + ie_length, top - itr + ie_length); | 345 | memmove(ie, ptr, size); |
| 508 | top -= ie_length; | 346 | ptr = ie; |
| 509 | new_len -= ie_length; | ||
| 510 | } | 347 | } |
| 511 | } | 348 | } |
| 512 | uwb_rc->ies->wIELength = cpu_to_le16(new_len); | 349 | uwb_rc->ies->wIELength = cpu_to_le16(len); |
| 513 | return 0; | ||
| 514 | } | 350 | } |
| 515 | 351 | ||
| 516 | 352 | ||
| 517 | /** | 353 | /** |
| 518 | * Remove an IE currently being transmitted by device | 354 | * uwb_rc_ie_rm - remove an IE from the radio controller's beacon |
| 355 | * @uwb_rc: the radio controller. | ||
| 356 | * @element_id: the element ID of the IE to remove. | ||
| 519 | * | 357 | * |
| 520 | * @element_id: id of IE to be removed from device's beacon | 358 | * Only IEs previously added with uwb_rc_ie_add() may be removed. |
| 359 | * | ||
| 360 | * Returns 0 on success; or -ve the SET-IE command to the radio | ||
| 361 | * controller failed. | ||
| 521 | */ | 362 | */ |
| 522 | int uwb_rc_ie_rm(struct uwb_rc *uwb_rc, enum uwb_ie element_id) | 363 | int uwb_rc_ie_rm(struct uwb_rc *uwb_rc, enum uwb_ie element_id) |
| 523 | { | 364 | { |
| 524 | struct device *dev = &uwb_rc->uwb_dev.dev; | 365 | int result = 0; |
| 525 | int result; | ||
| 526 | 366 | ||
| 527 | if (uwb_rc->ies == NULL) | ||
| 528 | return -ESHUTDOWN; | ||
| 529 | mutex_lock(&uwb_rc->ies_mutex); | 367 | mutex_lock(&uwb_rc->ies_mutex); |
| 530 | result = uwb_rc_ie_cache_rm(uwb_rc, element_id); | 368 | |
| 531 | if (result < 0) | 369 | uwb_rc_ie_cache_rm(uwb_rc, element_id); |
| 532 | dev_err(dev, "Cannot remove IE from cache.\n"); | 370 | |
| 533 | if (uwb_rc->beaconing != -1) { | 371 | if (uwb_rc->beaconing != -1) |
| 534 | result = uwb_rc_set_ie(uwb_rc, uwb_rc->ies); | 372 | result = uwb_rc_set_ie(uwb_rc, uwb_rc->ies); |
| 535 | if (result < 0) | 373 | |
| 536 | dev_err(dev, "Cannot set new IE on device.\n"); | ||
| 537 | } | ||
| 538 | mutex_unlock(&uwb_rc->ies_mutex); | 374 | mutex_unlock(&uwb_rc->ies_mutex); |
| 375 | |||
| 539 | return result; | 376 | return result; |
| 540 | } | 377 | } |
| 541 | EXPORT_SYMBOL_GPL(uwb_rc_ie_rm); | 378 | EXPORT_SYMBOL_GPL(uwb_rc_ie_rm); |
diff --git a/drivers/uwb/lc-dev.c b/drivers/uwb/lc-dev.c index 15f856c9689..e9fe1bb7eb2 100644 --- a/drivers/uwb/lc-dev.c +++ b/drivers/uwb/lc-dev.c | |||
| @@ -22,7 +22,6 @@ | |||
| 22 | * | 22 | * |
| 23 | * FIXME: docs | 23 | * FIXME: docs |
| 24 | */ | 24 | */ |
| 25 | |||
| 26 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
| 27 | #include <linux/device.h> | 26 | #include <linux/device.h> |
| 28 | #include <linux/err.h> | 27 | #include <linux/err.h> |
| @@ -30,10 +29,6 @@ | |||
| 30 | #include <linux/random.h> | 29 | #include <linux/random.h> |
| 31 | #include "uwb-internal.h" | 30 | #include "uwb-internal.h" |
| 32 | 31 | ||
| 33 | #define D_LOCAL 1 | ||
| 34 | #include <linux/uwb/debug.h> | ||
| 35 | |||
| 36 | |||
| 37 | /* We initialize addresses to 0xff (invalid, as it is bcast) */ | 32 | /* We initialize addresses to 0xff (invalid, as it is bcast) */ |
| 38 | static inline void uwb_dev_addr_init(struct uwb_dev_addr *addr) | 33 | static inline void uwb_dev_addr_init(struct uwb_dev_addr *addr) |
| 39 | { | 34 | { |
| @@ -104,12 +99,9 @@ static void uwb_dev_sys_release(struct device *dev) | |||
| 104 | { | 99 | { |
| 105 | struct uwb_dev *uwb_dev = to_uwb_dev(dev); | 100 | struct uwb_dev *uwb_dev = to_uwb_dev(dev); |
| 106 | 101 | ||
| 107 | d_fnstart(4, NULL, "(dev %p uwb_dev %p)\n", dev, uwb_dev); | ||
| 108 | uwb_bce_put(uwb_dev->bce); | 102 | uwb_bce_put(uwb_dev->bce); |
| 109 | d_printf(0, &uwb_dev->dev, "uwb_dev %p freed\n", uwb_dev); | ||
| 110 | memset(uwb_dev, 0x69, sizeof(*uwb_dev)); | 103 | memset(uwb_dev, 0x69, sizeof(*uwb_dev)); |
| 111 | kfree(uwb_dev); | 104 | kfree(uwb_dev); |
| 112 | d_fnend(4, NULL, "(dev %p uwb_dev %p) = void\n", dev, uwb_dev); | ||
| 113 | } | 105 | } |
| 114 | 106 | ||
| 115 | /* | 107 | /* |
| @@ -275,12 +267,8 @@ static struct attribute_group *groups[] = { | |||
| 275 | */ | 267 | */ |
| 276 | static int __uwb_dev_sys_add(struct uwb_dev *uwb_dev, struct device *parent_dev) | 268 | static int __uwb_dev_sys_add(struct uwb_dev *uwb_dev, struct device *parent_dev) |
| 277 | { | 269 | { |
| 278 | int result; | ||
| 279 | struct device *dev; | 270 | struct device *dev; |
| 280 | 271 | ||
| 281 | d_fnstart(4, NULL, "(uwb_dev %p parent_dev %p)\n", uwb_dev, parent_dev); | ||
| 282 | BUG_ON(parent_dev == NULL); | ||
| 283 | |||
| 284 | dev = &uwb_dev->dev; | 272 | dev = &uwb_dev->dev; |
| 285 | /* Device sysfs files are only useful for neighbor devices not | 273 | /* Device sysfs files are only useful for neighbor devices not |
| 286 | local radio controllers. */ | 274 | local radio controllers. */ |
| @@ -289,18 +277,14 @@ static int __uwb_dev_sys_add(struct uwb_dev *uwb_dev, struct device *parent_dev) | |||
| 289 | dev->parent = parent_dev; | 277 | dev->parent = parent_dev; |
| 290 | dev_set_drvdata(dev, uwb_dev); | 278 | dev_set_drvdata(dev, uwb_dev); |
| 291 | 279 | ||
| 292 | result = device_add(dev); | 280 | return device_add(dev); |
| 293 | d_fnend(4, NULL, "(uwb_dev %p parent_dev %p) = %d\n", uwb_dev, parent_dev, result); | ||
| 294 | return result; | ||
| 295 | } | 281 | } |
| 296 | 282 | ||
| 297 | 283 | ||
| 298 | static void __uwb_dev_sys_rm(struct uwb_dev *uwb_dev) | 284 | static void __uwb_dev_sys_rm(struct uwb_dev *uwb_dev) |
| 299 | { | 285 | { |
| 300 | d_fnstart(4, NULL, "(uwb_dev %p)\n", uwb_dev); | ||
| 301 | dev_set_drvdata(&uwb_dev->dev, NULL); | 286 | dev_set_drvdata(&uwb_dev->dev, NULL); |
| 302 | device_del(&uwb_dev->dev); | 287 | device_del(&uwb_dev->dev); |
| 303 | d_fnend(4, NULL, "(uwb_dev %p) = void\n", uwb_dev); | ||
| 304 | } | 288 | } |
| 305 | 289 | ||
| 306 | 290 | ||
| @@ -384,7 +368,6 @@ int __uwb_dev_offair(struct uwb_dev *uwb_dev, struct uwb_rc *rc) | |||
| 384 | struct device *dev = &uwb_dev->dev; | 368 | struct device *dev = &uwb_dev->dev; |
| 385 | char macbuf[UWB_ADDR_STRSIZE], devbuf[UWB_ADDR_STRSIZE]; | 369 | char macbuf[UWB_ADDR_STRSIZE], devbuf[UWB_ADDR_STRSIZE]; |
| 386 | 370 | ||
| 387 | d_fnstart(3, NULL, "(dev %p [uwb_dev %p], uwb_rc %p)\n", dev, uwb_dev, rc); | ||
| 388 | uwb_mac_addr_print(macbuf, sizeof(macbuf), &uwb_dev->mac_addr); | 371 | uwb_mac_addr_print(macbuf, sizeof(macbuf), &uwb_dev->mac_addr); |
| 389 | uwb_dev_addr_print(devbuf, sizeof(devbuf), &uwb_dev->dev_addr); | 372 | uwb_dev_addr_print(devbuf, sizeof(devbuf), &uwb_dev->dev_addr); |
| 390 | dev_info(dev, "uwb device (mac %s dev %s) disconnected from %s %s\n", | 373 | dev_info(dev, "uwb device (mac %s dev %s) disconnected from %s %s\n", |
| @@ -392,8 +375,10 @@ int __uwb_dev_offair(struct uwb_dev *uwb_dev, struct uwb_rc *rc) | |||
| 392 | rc ? rc->uwb_dev.dev.parent->bus->name : "n/a", | 375 | rc ? rc->uwb_dev.dev.parent->bus->name : "n/a", |
| 393 | rc ? dev_name(rc->uwb_dev.dev.parent) : ""); | 376 | rc ? dev_name(rc->uwb_dev.dev.parent) : ""); |
| 394 | uwb_dev_rm(uwb_dev); | 377 | uwb_dev_rm(uwb_dev); |
| 378 | list_del(&uwb_dev->bce->node); | ||
| 379 | uwb_bce_put(uwb_dev->bce); | ||
| 395 | uwb_dev_put(uwb_dev); /* for the creation in _onair() */ | 380 | uwb_dev_put(uwb_dev); /* for the creation in _onair() */ |
| 396 | d_fnend(3, NULL, "(dev %p [uwb_dev %p], uwb_rc %p) = 0\n", dev, uwb_dev, rc); | 381 | |
| 397 | return 0; | 382 | return 0; |
| 398 | } | 383 | } |
| 399 | 384 | ||
diff --git a/drivers/uwb/lc-rc.c b/drivers/uwb/lc-rc.c index ee5772f00d4..9cf21e6bb62 100644 --- a/drivers/uwb/lc-rc.c +++ b/drivers/uwb/lc-rc.c | |||
| @@ -36,8 +36,6 @@ | |||
| 36 | #include <linux/etherdevice.h> | 36 | #include <linux/etherdevice.h> |
| 37 | #include <linux/usb.h> | 37 | #include <linux/usb.h> |
| 38 | 38 | ||
| 39 | #define D_LOCAL 1 | ||
| 40 | #include <linux/uwb/debug.h> | ||
| 41 | #include "uwb-internal.h" | 39 | #include "uwb-internal.h" |
| 42 | 40 | ||
| 43 | static int uwb_rc_index_match(struct device *dev, void *data) | 41 | static int uwb_rc_index_match(struct device *dev, void *data) |
| @@ -81,9 +79,7 @@ static void uwb_rc_sys_release(struct device *dev) | |||
| 81 | struct uwb_dev *uwb_dev = container_of(dev, struct uwb_dev, dev); | 79 | struct uwb_dev *uwb_dev = container_of(dev, struct uwb_dev, dev); |
| 82 | struct uwb_rc *rc = container_of(uwb_dev, struct uwb_rc, uwb_dev); | 80 | struct uwb_rc *rc = container_of(uwb_dev, struct uwb_rc, uwb_dev); |
| 83 | 81 | ||
| 84 | uwb_rc_neh_destroy(rc); | ||
| 85 | uwb_rc_ie_release(rc); | 82 | uwb_rc_ie_release(rc); |
| 86 | d_printf(1, dev, "freed uwb_rc %p\n", rc); | ||
| 87 | kfree(rc); | 83 | kfree(rc); |
| 88 | } | 84 | } |
| 89 | 85 | ||
| @@ -100,6 +96,8 @@ void uwb_rc_init(struct uwb_rc *rc) | |||
| 100 | rc->scan_type = UWB_SCAN_DISABLED; | 96 | rc->scan_type = UWB_SCAN_DISABLED; |
| 101 | INIT_LIST_HEAD(&rc->notifs_chain.list); | 97 | INIT_LIST_HEAD(&rc->notifs_chain.list); |
| 102 | mutex_init(&rc->notifs_chain.mutex); | 98 | mutex_init(&rc->notifs_chain.mutex); |
| 99 | INIT_LIST_HEAD(&rc->uwb_beca.list); | ||
| 100 | mutex_init(&rc->uwb_beca.mutex); | ||
| 103 | uwb_drp_avail_init(rc); | 101 | uwb_drp_avail_init(rc); |
| 104 | uwb_rc_ie_init(rc); | 102 | uwb_rc_ie_init(rc); |
| 105 | uwb_rsv_init(rc); | 103 | uwb_rsv_init(rc); |
| @@ -191,9 +189,9 @@ static int uwb_rc_setup(struct uwb_rc *rc) | |||
| 191 | int result; | 189 | int result; |
| 192 | struct device *dev = &rc->uwb_dev.dev; | 190 | struct device *dev = &rc->uwb_dev.dev; |
| 193 | 191 | ||
| 194 | result = uwb_rc_reset(rc); | 192 | result = uwb_radio_setup(rc); |
| 195 | if (result < 0) { | 193 | if (result < 0) { |
| 196 | dev_err(dev, "cannot reset UWB radio: %d\n", result); | 194 | dev_err(dev, "cannot setup UWB radio: %d\n", result); |
| 197 | goto error; | 195 | goto error; |
| 198 | } | 196 | } |
| 199 | result = uwb_rc_mac_addr_setup(rc); | 197 | result = uwb_rc_mac_addr_setup(rc); |
| @@ -250,6 +248,12 @@ int uwb_rc_add(struct uwb_rc *rc, struct device *parent_dev, void *priv) | |||
| 250 | 248 | ||
| 251 | rc->priv = priv; | 249 | rc->priv = priv; |
| 252 | 250 | ||
| 251 | init_waitqueue_head(&rc->uwbd.wq); | ||
| 252 | INIT_LIST_HEAD(&rc->uwbd.event_list); | ||
| 253 | spin_lock_init(&rc->uwbd.event_list_lock); | ||
| 254 | |||
| 255 | uwbd_start(rc); | ||
| 256 | |||
| 253 | result = rc->start(rc); | 257 | result = rc->start(rc); |
| 254 | if (result < 0) | 258 | if (result < 0) |
| 255 | goto error_rc_start; | 259 | goto error_rc_start; |
| @@ -284,7 +288,7 @@ error_sys_add: | |||
| 284 | error_dev_add: | 288 | error_dev_add: |
| 285 | error_rc_setup: | 289 | error_rc_setup: |
| 286 | rc->stop(rc); | 290 | rc->stop(rc); |
| 287 | uwbd_flush(rc); | 291 | uwbd_stop(rc); |
| 288 | error_rc_start: | 292 | error_rc_start: |
| 289 | return result; | 293 | return result; |
| 290 | } | 294 | } |
| @@ -306,25 +310,24 @@ void uwb_rc_rm(struct uwb_rc *rc) | |||
| 306 | rc->ready = 0; | 310 | rc->ready = 0; |
| 307 | 311 | ||
| 308 | uwb_dbg_del_rc(rc); | 312 | uwb_dbg_del_rc(rc); |
| 309 | uwb_rsv_cleanup(rc); | 313 | uwb_rsv_remove_all(rc); |
| 310 | uwb_rc_ie_rm(rc, UWB_IDENTIFICATION_IE); | 314 | uwb_radio_shutdown(rc); |
| 311 | if (rc->beaconing >= 0) | ||
| 312 | uwb_rc_beacon(rc, -1, 0); | ||
| 313 | if (rc->scan_type != UWB_SCAN_DISABLED) | ||
| 314 | uwb_rc_scan(rc, rc->scanning, UWB_SCAN_DISABLED, 0); | ||
| 315 | uwb_rc_reset(rc); | ||
| 316 | 315 | ||
| 317 | rc->stop(rc); | 316 | rc->stop(rc); |
| 318 | uwbd_flush(rc); | 317 | |
| 318 | uwbd_stop(rc); | ||
| 319 | uwb_rc_neh_destroy(rc); | ||
| 319 | 320 | ||
| 320 | uwb_dev_lock(&rc->uwb_dev); | 321 | uwb_dev_lock(&rc->uwb_dev); |
| 321 | rc->priv = NULL; | 322 | rc->priv = NULL; |
| 322 | rc->cmd = NULL; | 323 | rc->cmd = NULL; |
| 323 | uwb_dev_unlock(&rc->uwb_dev); | 324 | uwb_dev_unlock(&rc->uwb_dev); |
| 324 | mutex_lock(&uwb_beca.mutex); | 325 | mutex_lock(&rc->uwb_beca.mutex); |
| 325 | uwb_dev_for_each(rc, uwb_dev_offair_helper, NULL); | 326 | uwb_dev_for_each(rc, uwb_dev_offair_helper, NULL); |
| 326 | __uwb_rc_sys_rm(rc); | 327 | __uwb_rc_sys_rm(rc); |
| 327 | mutex_unlock(&uwb_beca.mutex); | 328 | mutex_unlock(&rc->uwb_beca.mutex); |
| 329 | uwb_rsv_cleanup(rc); | ||
| 330 | uwb_beca_release(rc); | ||
| 328 | uwb_dev_rm(&rc->uwb_dev); | 331 | uwb_dev_rm(&rc->uwb_dev); |
| 329 | } | 332 | } |
| 330 | EXPORT_SYMBOL_GPL(uwb_rc_rm); | 333 | EXPORT_SYMBOL_GPL(uwb_rc_rm); |
| @@ -468,28 +471,3 @@ void uwb_rc_put(struct uwb_rc *rc) | |||
| 468 | __uwb_rc_put(rc); | 471 | __uwb_rc_put(rc); |
| 469 | } | 472 | } |
| 470 | EXPORT_SYMBOL_GPL(uwb_rc_put); | 473 | EXPORT_SYMBOL_GPL(uwb_rc_put); |
| 471 | |||
| 472 | /* | ||
| 473 | * | ||
| 474 | * | ||
| 475 | */ | ||
| 476 | ssize_t uwb_rc_print_IEs(struct uwb_rc *uwb_rc, char *buf, size_t size) | ||
| 477 | { | ||
| 478 | ssize_t result; | ||
| 479 | struct uwb_rc_evt_get_ie *ie_info; | ||
| 480 | struct uwb_buf_ctx ctx; | ||
| 481 | |||
| 482 | result = uwb_rc_get_ie(uwb_rc, &ie_info); | ||
| 483 | if (result < 0) | ||
| 484 | goto error_get_ie; | ||
| 485 | ctx.buf = buf; | ||
| 486 | ctx.size = size; | ||
| 487 | ctx.bytes = 0; | ||
| 488 | uwb_ie_for_each(&uwb_rc->uwb_dev, uwb_ie_dump_hex, &ctx, | ||
| 489 | ie_info->IEData, result - sizeof(*ie_info)); | ||
| 490 | result = ctx.bytes; | ||
| 491 | kfree(ie_info); | ||
| 492 | error_get_ie: | ||
| 493 | return result; | ||
| 494 | } | ||
| 495 | |||
diff --git a/drivers/uwb/neh.c b/drivers/uwb/neh.c index 9b4eb64327a..0af8916d9be 100644 --- a/drivers/uwb/neh.c +++ b/drivers/uwb/neh.c | |||
| @@ -86,8 +86,6 @@ | |||
| 86 | #include <linux/err.h> | 86 | #include <linux/err.h> |
| 87 | 87 | ||
| 88 | #include "uwb-internal.h" | 88 | #include "uwb-internal.h" |
| 89 | #define D_LOCAL 0 | ||
| 90 | #include <linux/uwb/debug.h> | ||
| 91 | 89 | ||
| 92 | /* | 90 | /* |
| 93 | * UWB Radio Controller Notification/Event Handle | 91 | * UWB Radio Controller Notification/Event Handle |
| @@ -254,7 +252,6 @@ error_kzalloc: | |||
| 254 | 252 | ||
| 255 | static void __uwb_rc_neh_rm(struct uwb_rc *rc, struct uwb_rc_neh *neh) | 253 | static void __uwb_rc_neh_rm(struct uwb_rc *rc, struct uwb_rc_neh *neh) |
| 256 | { | 254 | { |
| 257 | del_timer(&neh->timer); | ||
| 258 | __uwb_rc_ctx_put(rc, neh); | 255 | __uwb_rc_ctx_put(rc, neh); |
| 259 | list_del(&neh->list_node); | 256 | list_del(&neh->list_node); |
| 260 | } | 257 | } |
| @@ -275,6 +272,7 @@ void uwb_rc_neh_rm(struct uwb_rc *rc, struct uwb_rc_neh *neh) | |||
| 275 | __uwb_rc_neh_rm(rc, neh); | 272 | __uwb_rc_neh_rm(rc, neh); |
| 276 | spin_unlock_irqrestore(&rc->neh_lock, flags); | 273 | spin_unlock_irqrestore(&rc->neh_lock, flags); |
| 277 | 274 | ||
| 275 | del_timer_sync(&neh->timer); | ||
| 278 | uwb_rc_neh_put(neh); | 276 | uwb_rc_neh_put(neh); |
| 279 | } | 277 | } |
| 280 | 278 | ||
| @@ -349,7 +347,7 @@ struct uwb_rc_neh *uwb_rc_neh_lookup(struct uwb_rc *rc, | |||
| 349 | } | 347 | } |
| 350 | 348 | ||
| 351 | 349 | ||
| 352 | /** | 350 | /* |
| 353 | * Process notifications coming from the radio control interface | 351 | * Process notifications coming from the radio control interface |
| 354 | * | 352 | * |
| 355 | * @rc: UWB Radio Control Interface descriptor | 353 | * @rc: UWB Radio Control Interface descriptor |
| @@ -401,23 +399,6 @@ void uwb_rc_notif(struct uwb_rc *rc, struct uwb_rceb *rceb, ssize_t size) | |||
| 401 | uwb_evt->notif.size = size; | 399 | uwb_evt->notif.size = size; |
| 402 | uwb_evt->notif.rceb = rceb; | 400 | uwb_evt->notif.rceb = rceb; |
| 403 | 401 | ||
| 404 | switch (le16_to_cpu(rceb->wEvent)) { | ||
| 405 | /* Trap some vendor specific events | ||
| 406 | * | ||
| 407 | * FIXME: move this to handling in ptc-est, where we | ||
| 408 | * register a NULL event handler for these two guys | ||
| 409 | * using the Intel IDs. | ||
| 410 | */ | ||
| 411 | case 0x0103: | ||
| 412 | dev_info(dev, "FIXME: DEVICE ADD\n"); | ||
| 413 | return; | ||
| 414 | case 0x0104: | ||
| 415 | dev_info(dev, "FIXME: DEVICE RM\n"); | ||
| 416 | return; | ||
| 417 | default: | ||
| 418 | break; | ||
| 419 | } | ||
| 420 | |||
| 421 | uwbd_event_queue(uwb_evt); | 402 | uwbd_event_queue(uwb_evt); |
| 422 | } | 403 | } |
| 423 | 404 | ||
| @@ -438,9 +419,10 @@ static void uwb_rc_neh_grok_event(struct uwb_rc *rc, struct uwb_rceb *rceb, size | |||
| 438 | rceb->bEventContext, size); | 419 | rceb->bEventContext, size); |
| 439 | } else { | 420 | } else { |
| 440 | neh = uwb_rc_neh_lookup(rc, rceb); | 421 | neh = uwb_rc_neh_lookup(rc, rceb); |
| 441 | if (neh) | 422 | if (neh) { |
| 423 | del_timer_sync(&neh->timer); | ||
| 442 | uwb_rc_neh_cb(neh, rceb, size); | 424 | uwb_rc_neh_cb(neh, rceb, size); |
| 443 | else | 425 | } else |
| 444 | dev_warn(dev, "event 0x%02x/%04x/%02x (%zu bytes): nobody cared\n", | 426 | dev_warn(dev, "event 0x%02x/%04x/%02x (%zu bytes): nobody cared\n", |
| 445 | rceb->bEventType, le16_to_cpu(rceb->wEvent), | 427 | rceb->bEventType, le16_to_cpu(rceb->wEvent), |
| 446 | rceb->bEventContext, size); | 428 | rceb->bEventContext, size); |
| @@ -495,8 +477,6 @@ void uwb_rc_neh_grok(struct uwb_rc *rc, void *buf, size_t buf_size) | |||
| 495 | size_t size, real_size, event_size; | 477 | size_t size, real_size, event_size; |
| 496 | int needtofree; | 478 | int needtofree; |
| 497 | 479 | ||
| 498 | d_fnstart(3, dev, "(rc %p buf %p %zu buf_size)\n", rc, buf, buf_size); | ||
| 499 | d_printf(2, dev, "groking event block: %zu bytes\n", buf_size); | ||
| 500 | itr = buf; | 480 | itr = buf; |
| 501 | size = buf_size; | 481 | size = buf_size; |
| 502 | while (size > 0) { | 482 | while (size > 0) { |
| @@ -544,10 +524,7 @@ void uwb_rc_neh_grok(struct uwb_rc *rc, void *buf, size_t buf_size) | |||
| 544 | 524 | ||
| 545 | itr += real_size; | 525 | itr += real_size; |
| 546 | size -= real_size; | 526 | size -= real_size; |
| 547 | d_printf(2, dev, "consumed %zd bytes, %zu left\n", | ||
| 548 | event_size, size); | ||
| 549 | } | 527 | } |
| 550 | d_fnend(3, dev, "(rc %p buf %p %zu buf_size) = void\n", rc, buf, buf_size); | ||
| 551 | } | 528 | } |
| 552 | EXPORT_SYMBOL_GPL(uwb_rc_neh_grok); | 529 | EXPORT_SYMBOL_GPL(uwb_rc_neh_grok); |
| 553 | 530 | ||
| @@ -562,16 +539,22 @@ EXPORT_SYMBOL_GPL(uwb_rc_neh_grok); | |||
| 562 | */ | 539 | */ |
| 563 | void uwb_rc_neh_error(struct uwb_rc *rc, int error) | 540 | void uwb_rc_neh_error(struct uwb_rc *rc, int error) |
| 564 | { | 541 | { |
| 565 | struct uwb_rc_neh *neh, *next; | 542 | struct uwb_rc_neh *neh; |
| 566 | unsigned long flags; | 543 | unsigned long flags; |
| 567 | 544 | ||
| 568 | BUG_ON(error >= 0); | 545 | for (;;) { |
| 569 | spin_lock_irqsave(&rc->neh_lock, flags); | 546 | spin_lock_irqsave(&rc->neh_lock, flags); |
| 570 | list_for_each_entry_safe(neh, next, &rc->neh_list, list_node) { | 547 | if (list_empty(&rc->neh_list)) { |
| 548 | spin_unlock_irqrestore(&rc->neh_lock, flags); | ||
| 549 | break; | ||
| 550 | } | ||
| 551 | neh = list_first_entry(&rc->neh_list, struct uwb_rc_neh, list_node); | ||
| 571 | __uwb_rc_neh_rm(rc, neh); | 552 | __uwb_rc_neh_rm(rc, neh); |
| 553 | spin_unlock_irqrestore(&rc->neh_lock, flags); | ||
| 554 | |||
| 555 | del_timer_sync(&neh->timer); | ||
| 572 | uwb_rc_neh_cb(neh, NULL, error); | 556 | uwb_rc_neh_cb(neh, NULL, error); |
| 573 | } | 557 | } |
| 574 | spin_unlock_irqrestore(&rc->neh_lock, flags); | ||
| 575 | } | 558 | } |
| 576 | EXPORT_SYMBOL_GPL(uwb_rc_neh_error); | 559 | EXPORT_SYMBOL_GPL(uwb_rc_neh_error); |
| 577 | 560 | ||
| @@ -583,10 +566,14 @@ static void uwb_rc_neh_timer(unsigned long arg) | |||
| 583 | unsigned long flags; | 566 | unsigned long flags; |
| 584 | 567 | ||
| 585 | spin_lock_irqsave(&rc->neh_lock, flags); | 568 | spin_lock_irqsave(&rc->neh_lock, flags); |
| 586 | __uwb_rc_neh_rm(rc, neh); | 569 | if (neh->context) |
| 570 | __uwb_rc_neh_rm(rc, neh); | ||
| 571 | else | ||
| 572 | neh = NULL; | ||
| 587 | spin_unlock_irqrestore(&rc->neh_lock, flags); | 573 | spin_unlock_irqrestore(&rc->neh_lock, flags); |
| 588 | 574 | ||
| 589 | uwb_rc_neh_cb(neh, NULL, -ETIMEDOUT); | 575 | if (neh) |
| 576 | uwb_rc_neh_cb(neh, NULL, -ETIMEDOUT); | ||
| 590 | } | 577 | } |
| 591 | 578 | ||
| 592 | /** Initializes the @rc's neh subsystem | 579 | /** Initializes the @rc's neh subsystem |
| @@ -605,12 +592,19 @@ void uwb_rc_neh_create(struct uwb_rc *rc) | |||
| 605 | void uwb_rc_neh_destroy(struct uwb_rc *rc) | 592 | void uwb_rc_neh_destroy(struct uwb_rc *rc) |
| 606 | { | 593 | { |
| 607 | unsigned long flags; | 594 | unsigned long flags; |
| 608 | struct uwb_rc_neh *neh, *next; | 595 | struct uwb_rc_neh *neh; |
| 609 | 596 | ||
| 610 | spin_lock_irqsave(&rc->neh_lock, flags); | 597 | for (;;) { |
| 611 | list_for_each_entry_safe(neh, next, &rc->neh_list, list_node) { | 598 | spin_lock_irqsave(&rc->neh_lock, flags); |
| 599 | if (list_empty(&rc->neh_list)) { | ||
| 600 | spin_unlock_irqrestore(&rc->neh_lock, flags); | ||
| 601 | break; | ||
| 602 | } | ||
| 603 | neh = list_first_entry(&rc->neh_list, struct uwb_rc_neh, list_node); | ||
| 612 | __uwb_rc_neh_rm(rc, neh); | 604 | __uwb_rc_neh_rm(rc, neh); |
| 605 | spin_unlock_irqrestore(&rc->neh_lock, flags); | ||
| 606 | |||
| 607 | del_timer_sync(&neh->timer); | ||
| 613 | uwb_rc_neh_put(neh); | 608 | uwb_rc_neh_put(neh); |
| 614 | } | 609 | } |
| 615 | spin_unlock_irqrestore(&rc->neh_lock, flags); | ||
| 616 | } | 610 | } |
diff --git a/drivers/uwb/pal.c b/drivers/uwb/pal.c index 1afb38eacb9..99a19c19909 100644 --- a/drivers/uwb/pal.c +++ b/drivers/uwb/pal.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 17 | */ | 17 | */ |
| 18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
| 19 | #include <linux/debugfs.h> | ||
| 19 | #include <linux/uwb.h> | 20 | #include <linux/uwb.h> |
| 20 | 21 | ||
| 21 | #include "uwb-internal.h" | 22 | #include "uwb-internal.h" |
| @@ -32,13 +33,13 @@ EXPORT_SYMBOL_GPL(uwb_pal_init); | |||
| 32 | 33 | ||
| 33 | /** | 34 | /** |
| 34 | * uwb_pal_register - register a UWB PAL | 35 | * uwb_pal_register - register a UWB PAL |
| 35 | * @rc: the radio controller the PAL will be using | ||
| 36 | * @pal: the PAL | 36 | * @pal: the PAL |
| 37 | * | 37 | * |
| 38 | * The PAL must be initialized with uwb_pal_init(). | 38 | * The PAL must be initialized with uwb_pal_init(). |
| 39 | */ | 39 | */ |
| 40 | int uwb_pal_register(struct uwb_rc *rc, struct uwb_pal *pal) | 40 | int uwb_pal_register(struct uwb_pal *pal) |
| 41 | { | 41 | { |
| 42 | struct uwb_rc *rc = pal->rc; | ||
| 42 | int ret; | 43 | int ret; |
| 43 | 44 | ||
| 44 | if (pal->device) { | 45 | if (pal->device) { |
| @@ -54,9 +55,11 @@ int uwb_pal_register(struct uwb_rc *rc, struct uwb_pal *pal) | |||
| 54 | } | 55 | } |
| 55 | } | 56 | } |
| 56 | 57 | ||
| 57 | spin_lock(&rc->pal_lock); | 58 | pal->debugfs_dir = uwb_dbg_create_pal_dir(pal); |
| 59 | |||
| 60 | mutex_lock(&rc->uwb_dev.mutex); | ||
| 58 | list_add(&pal->node, &rc->pals); | 61 | list_add(&pal->node, &rc->pals); |
| 59 | spin_unlock(&rc->pal_lock); | 62 | mutex_unlock(&rc->uwb_dev.mutex); |
| 60 | 63 | ||
| 61 | return 0; | 64 | return 0; |
| 62 | } | 65 | } |
| @@ -64,14 +67,19 @@ EXPORT_SYMBOL_GPL(uwb_pal_register); | |||
| 64 | 67 | ||
| 65 | /** | 68 | /** |
| 66 | * uwb_pal_register - unregister a UWB PAL | 69 | * uwb_pal_register - unregister a UWB PAL |
| 67 | * @rc: the radio controller the PAL was using | ||
| 68 | * @pal: the PAL | 70 | * @pal: the PAL |
| 69 | */ | 71 | */ |
| 70 | void uwb_pal_unregister(struct uwb_rc *rc, struct uwb_pal *pal) | 72 | void uwb_pal_unregister(struct uwb_pal *pal) |
| 71 | { | 73 | { |
| 72 | spin_lock(&rc->pal_lock); | 74 | struct uwb_rc *rc = pal->rc; |
| 75 | |||
| 76 | uwb_radio_stop(pal); | ||
| 77 | |||
| 78 | mutex_lock(&rc->uwb_dev.mutex); | ||
| 73 | list_del(&pal->node); | 79 | list_del(&pal->node); |
| 74 | spin_unlock(&rc->pal_lock); | 80 | mutex_unlock(&rc->uwb_dev.mutex); |
| 81 | |||
| 82 | debugfs_remove(pal->debugfs_dir); | ||
| 75 | 83 | ||
| 76 | if (pal->device) { | 84 | if (pal->device) { |
| 77 | sysfs_remove_link(&rc->uwb_dev.dev.kobj, pal->name); | 85 | sysfs_remove_link(&rc->uwb_dev.dev.kobj, pal->name); |
| @@ -86,6 +94,5 @@ EXPORT_SYMBOL_GPL(uwb_pal_unregister); | |||
| 86 | */ | 94 | */ |
| 87 | void uwb_rc_pal_init(struct uwb_rc *rc) | 95 | void uwb_rc_pal_init(struct uwb_rc *rc) |
| 88 | { | 96 | { |
| 89 | spin_lock_init(&rc->pal_lock); | ||
| 90 | INIT_LIST_HEAD(&rc->pals); | 97 | INIT_LIST_HEAD(&rc->pals); |
| 91 | } | 98 | } |
diff --git a/drivers/uwb/radio.c b/drivers/uwb/radio.c new file mode 100644 index 00000000000..f0d55495f5e --- /dev/null +++ b/drivers/uwb/radio.c | |||
| @@ -0,0 +1,202 @@ | |||
| 1 | /* | ||
| 2 | * UWB radio (channel) management. | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008 Cambridge Silicon Radio Ltd. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public License version | ||
| 8 | * 2 as published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 17 | */ | ||
| 18 | #include <linux/kernel.h> | ||
| 19 | #include <linux/uwb.h> | ||
| 20 | |||
| 21 | #include "uwb-internal.h" | ||
| 22 | |||
| 23 | |||
| 24 | static int uwb_radio_select_channel(struct uwb_rc *rc) | ||
| 25 | { | ||
| 26 | /* | ||
| 27 | * Default to channel 9 (BG1, TFC1) unless the user has | ||
| 28 | * selected a specific channel or there are no active PALs. | ||
| 29 | */ | ||
| 30 | if (rc->active_pals == 0) | ||
| 31 | return -1; | ||
| 32 | if (rc->beaconing_forced) | ||
| 33 | return rc->beaconing_forced; | ||
| 34 | return 9; | ||
| 35 | } | ||
| 36 | |||
| 37 | |||
| 38 | /* | ||
| 39 | * Notify all active PALs that the channel has changed. | ||
| 40 | */ | ||
| 41 | static void uwb_radio_channel_changed(struct uwb_rc *rc, int channel) | ||
| 42 | { | ||
| 43 | struct uwb_pal *pal; | ||
| 44 | |||
| 45 | list_for_each_entry(pal, &rc->pals, node) { | ||
| 46 | if (pal->channel && channel != pal->channel) { | ||
| 47 | pal->channel = channel; | ||
| 48 | if (pal->channel_changed) | ||
| 49 | pal->channel_changed(pal, pal->channel); | ||
| 50 | } | ||
| 51 | } | ||
| 52 | } | ||
| 53 | |||
| 54 | /* | ||
| 55 | * Change to a new channel and notify any active PALs of the new | ||
| 56 | * channel. | ||
| 57 | * | ||
| 58 | * When stopping the radio, PALs need to be notified first so they can | ||
| 59 | * terminate any active reservations. | ||
| 60 | */ | ||
| 61 | static int uwb_radio_change_channel(struct uwb_rc *rc, int channel) | ||
| 62 | { | ||
| 63 | int ret = 0; | ||
| 64 | |||
| 65 | if (channel == -1) | ||
| 66 | uwb_radio_channel_changed(rc, channel); | ||
| 67 | |||
| 68 | if (channel != rc->beaconing) { | ||
| 69 | if (rc->beaconing != -1 && channel != -1) { | ||
| 70 | /* | ||
| 71 | * FIXME: should signal the channel change | ||
| 72 | * with a Channel Change IE. | ||
| 73 | */ | ||
| 74 | ret = uwb_radio_change_channel(rc, -1); | ||
| 75 | if (ret < 0) | ||
| 76 | return ret; | ||
| 77 | } | ||
| 78 | ret = uwb_rc_beacon(rc, channel, 0); | ||
| 79 | } | ||
| 80 | |||
| 81 | if (channel != -1) | ||
| 82 | uwb_radio_channel_changed(rc, rc->beaconing); | ||
| 83 | |||
| 84 | return ret; | ||
| 85 | } | ||
| 86 | |||
| 87 | /** | ||
| 88 | * uwb_radio_start - request that the radio be started | ||
| 89 | * @pal: the PAL making the request. | ||
| 90 | * | ||
| 91 | * If the radio is not already active, aa suitable channel is selected | ||
| 92 | * and beacons are started. | ||
| 93 | */ | ||
| 94 | int uwb_radio_start(struct uwb_pal *pal) | ||
| 95 | { | ||
| 96 | struct uwb_rc *rc = pal->rc; | ||
| 97 | int ret = 0; | ||
| 98 | |||
| 99 | mutex_lock(&rc->uwb_dev.mutex); | ||
| 100 | |||
| 101 | if (!pal->channel) { | ||
| 102 | pal->channel = -1; | ||
| 103 | rc->active_pals++; | ||
| 104 | ret = uwb_radio_change_channel(rc, uwb_radio_select_channel(rc)); | ||
| 105 | } | ||
| 106 | |||
| 107 | mutex_unlock(&rc->uwb_dev.mutex); | ||
| 108 | return ret; | ||
| 109 | } | ||
| 110 | EXPORT_SYMBOL_GPL(uwb_radio_start); | ||
| 111 | |||
| 112 | /** | ||
| 113 | * uwb_radio_stop - request tha the radio be stopped. | ||
| 114 | * @pal: the PAL making the request. | ||
| 115 | * | ||
| 116 | * Stops the radio if no other PAL is making use of it. | ||
| 117 | */ | ||
| 118 | void uwb_radio_stop(struct uwb_pal *pal) | ||
| 119 | { | ||
| 120 | struct uwb_rc *rc = pal->rc; | ||
| 121 | |||
| 122 | mutex_lock(&rc->uwb_dev.mutex); | ||
| 123 | |||
| 124 | if (pal->channel) { | ||
| 125 | rc->active_pals--; | ||
| 126 | uwb_radio_change_channel(rc, uwb_radio_select_channel(rc)); | ||
| 127 | pal->channel = 0; | ||
| 128 | } | ||
| 129 | |||
| 130 | mutex_unlock(&rc->uwb_dev.mutex); | ||
| 131 | } | ||
| 132 | EXPORT_SYMBOL_GPL(uwb_radio_stop); | ||
| 133 | |||
| 134 | /* | ||
| 135 | * uwb_radio_force_channel - force a specific channel to be used | ||
| 136 | * @rc: the radio controller. | ||
| 137 | * @channel: the channel to use; -1 to force the radio to stop; 0 to | ||
| 138 | * use the default channel selection algorithm. | ||
| 139 | */ | ||
| 140 | int uwb_radio_force_channel(struct uwb_rc *rc, int channel) | ||
| 141 | { | ||
| 142 | int ret = 0; | ||
| 143 | |||
| 144 | mutex_lock(&rc->uwb_dev.mutex); | ||
| 145 | |||
| 146 | rc->beaconing_forced = channel; | ||
| 147 | ret = uwb_radio_change_channel(rc, uwb_radio_select_channel(rc)); | ||
| 148 | |||
| 149 | mutex_unlock(&rc->uwb_dev.mutex); | ||
| 150 | return ret; | ||
| 151 | } | ||
| 152 | |||
| 153 | /* | ||
| 154 | * uwb_radio_setup - setup the radio manager | ||
| 155 | * @rc: the radio controller. | ||
| 156 | * | ||
| 157 | * The radio controller is reset to ensure it's in a known state | ||
| 158 | * before it's used. | ||
| 159 | */ | ||
| 160 | int uwb_radio_setup(struct uwb_rc *rc) | ||
| 161 | { | ||
| 162 | return uwb_rc_reset(rc); | ||
| 163 | } | ||
| 164 | |||
| 165 | /* | ||
| 166 | * uwb_radio_reset_state - reset any radio manager state | ||
| 167 | * @rc: the radio controller. | ||
| 168 | * | ||
| 169 | * All internal radio manager state is reset to values corresponding | ||
| 170 | * to a reset radio controller. | ||
| 171 | */ | ||
| 172 | void uwb_radio_reset_state(struct uwb_rc *rc) | ||
| 173 | { | ||
| 174 | struct uwb_pal *pal; | ||
| 175 | |||
| 176 | mutex_lock(&rc->uwb_dev.mutex); | ||
| 177 | |||
| 178 | list_for_each_entry(pal, &rc->pals, node) { | ||
| 179 | if (pal->channel) { | ||
| 180 | pal->channel = -1; | ||
| 181 | if (pal->channel_changed) | ||
| 182 | pal->channel_changed(pal, -1); | ||
| 183 | } | ||
| 184 | } | ||
| 185 | |||
| 186 | rc->beaconing = -1; | ||
| 187 | rc->scanning = -1; | ||
| 188 | |||
| 189 | mutex_unlock(&rc->uwb_dev.mutex); | ||
| 190 | } | ||
| 191 | |||
| 192 | /* | ||
| 193 | * uwb_radio_shutdown - shutdown the radio manager | ||
| 194 | * @rc: the radio controller. | ||
| 195 | * | ||
| 196 | * The radio controller is reset. | ||
| 197 | */ | ||
| 198 | void uwb_radio_shutdown(struct uwb_rc *rc) | ||
| 199 | { | ||
| 200 | uwb_radio_reset_state(rc); | ||
| 201 | uwb_rc_reset(rc); | ||
| 202 | } | ||
diff --git a/drivers/uwb/reset.c b/drivers/uwb/reset.c index 8de856fa795..70f8050221f 100644 --- a/drivers/uwb/reset.c +++ b/drivers/uwb/reset.c | |||
| @@ -32,8 +32,6 @@ | |||
| 32 | #include <linux/err.h> | 32 | #include <linux/err.h> |
| 33 | 33 | ||
| 34 | #include "uwb-internal.h" | 34 | #include "uwb-internal.h" |
| 35 | #define D_LOCAL 0 | ||
| 36 | #include <linux/uwb/debug.h> | ||
| 37 | 35 | ||
| 38 | /** | 36 | /** |
| 39 | * Command result codes (WUSB1.0[T8-69]) | 37 | * Command result codes (WUSB1.0[T8-69]) |
| @@ -323,17 +321,16 @@ int uwbd_msg_handle_reset(struct uwb_event *evt) | |||
| 323 | struct uwb_rc *rc = evt->rc; | 321 | struct uwb_rc *rc = evt->rc; |
| 324 | int ret; | 322 | int ret; |
| 325 | 323 | ||
| 326 | /* Need to prevent the RC hardware module going away while in | ||
| 327 | the rc->reset() call. */ | ||
| 328 | if (!try_module_get(rc->owner)) | ||
| 329 | return 0; | ||
| 330 | |||
| 331 | dev_info(&rc->uwb_dev.dev, "resetting radio controller\n"); | 324 | dev_info(&rc->uwb_dev.dev, "resetting radio controller\n"); |
| 332 | ret = rc->reset(rc); | 325 | ret = rc->reset(rc); |
| 333 | if (ret) | 326 | if (ret) { |
| 334 | dev_err(&rc->uwb_dev.dev, "failed to reset hardware: %d\n", ret); | 327 | dev_err(&rc->uwb_dev.dev, "failed to reset hardware: %d\n", ret); |
| 335 | 328 | goto error; | |
| 336 | module_put(rc->owner); | 329 | } |
| 330 | return 0; | ||
| 331 | error: | ||
| 332 | /* Nothing can be done except try the reset again. */ | ||
| 333 | uwb_rc_reset_all(rc); | ||
| 337 | return ret; | 334 | return ret; |
| 338 | } | 335 | } |
| 339 | 336 | ||
| @@ -360,3 +357,33 @@ void uwb_rc_reset_all(struct uwb_rc *rc) | |||
| 360 | uwbd_event_queue(evt); | 357 | uwbd_event_queue(evt); |
| 361 | } | 358 | } |
| 362 | EXPORT_SYMBOL_GPL(uwb_rc_reset_all); | 359 | EXPORT_SYMBOL_GPL(uwb_rc_reset_all); |
| 360 | |||
| 361 | void uwb_rc_pre_reset(struct uwb_rc *rc) | ||
| 362 | { | ||
| 363 | rc->stop(rc); | ||
| 364 | uwbd_flush(rc); | ||
| 365 | |||
| 366 | uwb_radio_reset_state(rc); | ||
| 367 | uwb_rsv_remove_all(rc); | ||
| 368 | } | ||
| 369 | EXPORT_SYMBOL_GPL(uwb_rc_pre_reset); | ||
| 370 | |||
| 371 | void uwb_rc_post_reset(struct uwb_rc *rc) | ||
| 372 | { | ||
| 373 | int ret; | ||
| 374 | |||
| 375 | ret = rc->start(rc); | ||
| 376 | if (ret) | ||
| 377 | goto error; | ||
| 378 | ret = uwb_rc_mac_addr_set(rc, &rc->uwb_dev.mac_addr); | ||
| 379 | if (ret) | ||
| 380 | goto error; | ||
| 381 | ret = uwb_rc_dev_addr_set(rc, &rc->uwb_dev.dev_addr); | ||
| 382 | if (ret) | ||
| 383 | goto error; | ||
| 384 | return; | ||
| 385 | error: | ||
| 386 | /* Nothing can be done except try the reset again. */ | ||
| 387 | uwb_rc_reset_all(rc); | ||
| 388 | } | ||
| 389 | EXPORT_SYMBOL_GPL(uwb_rc_post_reset); | ||
diff --git a/drivers/uwb/rsv.c b/drivers/uwb/rsv.c index bae16204576..ec6eecb32f3 100644 --- a/drivers/uwb/rsv.c +++ b/drivers/uwb/rsv.c | |||
| @@ -15,23 +15,33 @@ | |||
| 15 | * You should have received a copy of the GNU General Public License | 15 | * You should have received a copy of the GNU General Public License |
| 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 17 | */ | 17 | */ |
| 18 | #include <linux/version.h> | ||
| 19 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
| 20 | #include <linux/uwb.h> | 19 | #include <linux/uwb.h> |
| 20 | #include <linux/random.h> | ||
| 21 | 21 | ||
| 22 | #include "uwb-internal.h" | 22 | #include "uwb-internal.h" |
| 23 | 23 | ||
| 24 | static void uwb_rsv_timer(unsigned long arg); | 24 | static void uwb_rsv_timer(unsigned long arg); |
| 25 | 25 | ||
| 26 | static const char *rsv_states[] = { | 26 | static const char *rsv_states[] = { |
| 27 | [UWB_RSV_STATE_NONE] = "none", | 27 | [UWB_RSV_STATE_NONE] = "none ", |
| 28 | [UWB_RSV_STATE_O_INITIATED] = "initiated", | 28 | [UWB_RSV_STATE_O_INITIATED] = "o initiated ", |
| 29 | [UWB_RSV_STATE_O_PENDING] = "pending", | 29 | [UWB_RSV_STATE_O_PENDING] = "o pending ", |
| 30 | [UWB_RSV_STATE_O_MODIFIED] = "modified", | 30 | [UWB_RSV_STATE_O_MODIFIED] = "o modified ", |
| 31 | [UWB_RSV_STATE_O_ESTABLISHED] = "established", | 31 | [UWB_RSV_STATE_O_ESTABLISHED] = "o established ", |
| 32 | [UWB_RSV_STATE_T_ACCEPTED] = "accepted", | 32 | [UWB_RSV_STATE_O_TO_BE_MOVED] = "o to be moved ", |
| 33 | [UWB_RSV_STATE_T_DENIED] = "denied", | 33 | [UWB_RSV_STATE_O_MOVE_EXPANDING] = "o move expanding", |
| 34 | [UWB_RSV_STATE_T_PENDING] = "pending", | 34 | [UWB_RSV_STATE_O_MOVE_COMBINING] = "o move combining", |
| 35 | [UWB_RSV_STATE_O_MOVE_REDUCING] = "o move reducing ", | ||
| 36 | [UWB_RSV_STATE_T_ACCEPTED] = "t accepted ", | ||
| 37 | [UWB_RSV_STATE_T_CONFLICT] = "t conflict ", | ||
| 38 | [UWB_RSV_STATE_T_PENDING] = "t pending ", | ||
| 39 | [UWB_RSV_STATE_T_DENIED] = "t denied ", | ||
| 40 | [UWB_RSV_STATE_T_RESIZED] = "t resized ", | ||
| 41 | [UWB_RSV_STATE_T_EXPANDING_ACCEPTED] = "t expanding acc ", | ||
| 42 | [UWB_RSV_STATE_T_EXPANDING_CONFLICT] = "t expanding conf", | ||
| 43 | [UWB_RSV_STATE_T_EXPANDING_PENDING] = "t expanding pend", | ||
| 44 | [UWB_RSV_STATE_T_EXPANDING_DENIED] = "t expanding den ", | ||
| 35 | }; | 45 | }; |
| 36 | 46 | ||
| 37 | static const char *rsv_types[] = { | 47 | static const char *rsv_types[] = { |
| @@ -42,6 +52,31 @@ static const char *rsv_types[] = { | |||
| 42 | [UWB_DRP_TYPE_PCA] = "pca", | 52 | [UWB_DRP_TYPE_PCA] = "pca", |
| 43 | }; | 53 | }; |
| 44 | 54 | ||
| 55 | bool uwb_rsv_has_two_drp_ies(struct uwb_rsv *rsv) | ||
| 56 | { | ||
| 57 | static const bool has_two_drp_ies[] = { | ||
| 58 | [UWB_RSV_STATE_O_INITIATED] = false, | ||
| 59 | [UWB_RSV_STATE_O_PENDING] = false, | ||
| 60 | [UWB_RSV_STATE_O_MODIFIED] = false, | ||
| 61 | [UWB_RSV_STATE_O_ESTABLISHED] = false, | ||
| 62 | [UWB_RSV_STATE_O_TO_BE_MOVED] = false, | ||
| 63 | [UWB_RSV_STATE_O_MOVE_COMBINING] = false, | ||
| 64 | [UWB_RSV_STATE_O_MOVE_REDUCING] = false, | ||
| 65 | [UWB_RSV_STATE_O_MOVE_EXPANDING] = true, | ||
| 66 | [UWB_RSV_STATE_T_ACCEPTED] = false, | ||
| 67 | [UWB_RSV_STATE_T_CONFLICT] = false, | ||
| 68 | [UWB_RSV_STATE_T_PENDING] = false, | ||
| 69 | [UWB_RSV_STATE_T_DENIED] = false, | ||
| 70 | [UWB_RSV_STATE_T_RESIZED] = false, | ||
| 71 | [UWB_RSV_STATE_T_EXPANDING_ACCEPTED] = true, | ||
| 72 | [UWB_RSV_STATE_T_EXPANDING_CONFLICT] = true, | ||
| 73 | [UWB_RSV_STATE_T_EXPANDING_PENDING] = true, | ||
| 74 | [UWB_RSV_STATE_T_EXPANDING_DENIED] = true, | ||
| 75 | }; | ||
| 76 | |||
| 77 | return has_two_drp_ies[rsv->state]; | ||
| 78 | } | ||
| 79 | |||
| 45 | /** | 80 | /** |
| 46 | * uwb_rsv_state_str - return a string for a reservation state | 81 | * uwb_rsv_state_str - return a string for a reservation state |
| 47 | * @state: the reservation state. | 82 | * @state: the reservation state. |
| @@ -66,7 +101,7 @@ const char *uwb_rsv_type_str(enum uwb_drp_type type) | |||
| 66 | } | 101 | } |
| 67 | EXPORT_SYMBOL_GPL(uwb_rsv_type_str); | 102 | EXPORT_SYMBOL_GPL(uwb_rsv_type_str); |
| 68 | 103 | ||
| 69 | static void uwb_rsv_dump(struct uwb_rsv *rsv) | 104 | void uwb_rsv_dump(char *text, struct uwb_rsv *rsv) |
| 70 | { | 105 | { |
| 71 | struct device *dev = &rsv->rc->uwb_dev.dev; | 106 | struct device *dev = &rsv->rc->uwb_dev.dev; |
| 72 | struct uwb_dev_addr devaddr; | 107 | struct uwb_dev_addr devaddr; |
| @@ -82,6 +117,23 @@ static void uwb_rsv_dump(struct uwb_rsv *rsv) | |||
| 82 | dev_dbg(dev, "rsv %s -> %s: %s\n", owner, target, uwb_rsv_state_str(rsv->state)); | 117 | dev_dbg(dev, "rsv %s -> %s: %s\n", owner, target, uwb_rsv_state_str(rsv->state)); |
| 83 | } | 118 | } |
| 84 | 119 | ||
| 120 | static void uwb_rsv_release(struct kref *kref) | ||
| 121 | { | ||
| 122 | struct uwb_rsv *rsv = container_of(kref, struct uwb_rsv, kref); | ||
| 123 | |||
| 124 | kfree(rsv); | ||
| 125 | } | ||
| 126 | |||
| 127 | void uwb_rsv_get(struct uwb_rsv *rsv) | ||
| 128 | { | ||
| 129 | kref_get(&rsv->kref); | ||
| 130 | } | ||
| 131 | |||
| 132 | void uwb_rsv_put(struct uwb_rsv *rsv) | ||
| 133 | { | ||
| 134 | kref_put(&rsv->kref, uwb_rsv_release); | ||
| 135 | } | ||
| 136 | |||
| 85 | /* | 137 | /* |
| 86 | * Get a free stream index for a reservation. | 138 | * Get a free stream index for a reservation. |
| 87 | * | 139 | * |
| @@ -92,6 +144,7 @@ static void uwb_rsv_dump(struct uwb_rsv *rsv) | |||
| 92 | static int uwb_rsv_get_stream(struct uwb_rsv *rsv) | 144 | static int uwb_rsv_get_stream(struct uwb_rsv *rsv) |
| 93 | { | 145 | { |
| 94 | struct uwb_rc *rc = rsv->rc; | 146 | struct uwb_rc *rc = rsv->rc; |
| 147 | struct device *dev = &rc->uwb_dev.dev; | ||
| 95 | unsigned long *streams_bm; | 148 | unsigned long *streams_bm; |
| 96 | int stream; | 149 | int stream; |
| 97 | 150 | ||
| @@ -113,12 +166,15 @@ static int uwb_rsv_get_stream(struct uwb_rsv *rsv) | |||
| 113 | rsv->stream = stream; | 166 | rsv->stream = stream; |
| 114 | set_bit(stream, streams_bm); | 167 | set_bit(stream, streams_bm); |
| 115 | 168 | ||
| 169 | dev_dbg(dev, "get stream %d\n", rsv->stream); | ||
| 170 | |||
| 116 | return 0; | 171 | return 0; |
| 117 | } | 172 | } |
| 118 | 173 | ||
| 119 | static void uwb_rsv_put_stream(struct uwb_rsv *rsv) | 174 | static void uwb_rsv_put_stream(struct uwb_rsv *rsv) |
| 120 | { | 175 | { |
| 121 | struct uwb_rc *rc = rsv->rc; | 176 | struct uwb_rc *rc = rsv->rc; |
| 177 | struct device *dev = &rc->uwb_dev.dev; | ||
| 122 | unsigned long *streams_bm; | 178 | unsigned long *streams_bm; |
| 123 | 179 | ||
| 124 | switch (rsv->target.type) { | 180 | switch (rsv->target.type) { |
| @@ -133,86 +189,52 @@ static void uwb_rsv_put_stream(struct uwb_rsv *rsv) | |||
| 133 | } | 189 | } |
| 134 | 190 | ||
| 135 | clear_bit(rsv->stream, streams_bm); | 191 | clear_bit(rsv->stream, streams_bm); |
| 192 | |||
| 193 | dev_dbg(dev, "put stream %d\n", rsv->stream); | ||
| 136 | } | 194 | } |
| 137 | 195 | ||
| 138 | /* | 196 | void uwb_rsv_backoff_win_timer(unsigned long arg) |
| 139 | * Generate a MAS allocation with a single row component. | ||
| 140 | */ | ||
| 141 | static void uwb_rsv_gen_alloc_row(struct uwb_mas_bm *mas, | ||
| 142 | int first_mas, int mas_per_zone, | ||
| 143 | int zs, int ze) | ||
| 144 | { | 197 | { |
| 145 | struct uwb_mas_bm col; | 198 | struct uwb_drp_backoff_win *bow = (struct uwb_drp_backoff_win *)arg; |
| 146 | int z; | 199 | struct uwb_rc *rc = container_of(bow, struct uwb_rc, bow); |
| 147 | 200 | struct device *dev = &rc->uwb_dev.dev; | |
| 148 | bitmap_zero(mas->bm, UWB_NUM_MAS); | 201 | |
| 149 | bitmap_zero(col.bm, UWB_NUM_MAS); | 202 | bow->can_reserve_extra_mases = true; |
| 150 | bitmap_fill(col.bm, mas_per_zone); | 203 | if (bow->total_expired <= 4) { |
| 151 | bitmap_shift_left(col.bm, col.bm, first_mas + zs * UWB_MAS_PER_ZONE, UWB_NUM_MAS); | 204 | bow->total_expired++; |
| 152 | 205 | } else { | |
| 153 | for (z = zs; z <= ze; z++) { | 206 | /* after 4 backoff window has expired we can exit from |
| 154 | bitmap_or(mas->bm, mas->bm, col.bm, UWB_NUM_MAS); | 207 | * the backoff procedure */ |
| 155 | bitmap_shift_left(col.bm, col.bm, UWB_MAS_PER_ZONE, UWB_NUM_MAS); | 208 | bow->total_expired = 0; |
| 209 | bow->window = UWB_DRP_BACKOFF_WIN_MIN >> 1; | ||
| 156 | } | 210 | } |
| 211 | dev_dbg(dev, "backoff_win_timer total_expired=%d, n=%d\n: ", bow->total_expired, bow->n); | ||
| 212 | |||
| 213 | /* try to relocate all the "to be moved" relocations */ | ||
| 214 | uwb_rsv_handle_drp_avail_change(rc); | ||
| 157 | } | 215 | } |
| 158 | 216 | ||
| 159 | /* | 217 | void uwb_rsv_backoff_win_increment(struct uwb_rc *rc) |
| 160 | * Allocate some MAS for this reservation based on current local | ||
| 161 | * availability, the reservation parameters (max_mas, min_mas, | ||
| 162 | * sparsity), and the WiMedia rules for MAS allocations. | ||
| 163 | * | ||
| 164 | * Returns -EBUSY is insufficient free MAS are available. | ||
| 165 | * | ||
| 166 | * FIXME: to simplify this, only safe reservations with a single row | ||
| 167 | * component in zones 1 to 15 are tried (zone 0 is skipped to avoid | ||
| 168 | * problems with the MAS reserved for the BP). | ||
| 169 | * | ||
| 170 | * [ECMA-368] section B.2. | ||
| 171 | */ | ||
| 172 | static int uwb_rsv_alloc_mas(struct uwb_rsv *rsv) | ||
| 173 | { | 218 | { |
| 174 | static const int safe_mas_in_row[UWB_NUM_ZONES] = { | 219 | struct uwb_drp_backoff_win *bow = &rc->bow; |
| 175 | 8, 7, 6, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 2, 1, | 220 | struct device *dev = &rc->uwb_dev.dev; |
| 176 | }; | 221 | unsigned timeout_us; |
| 177 | int n, r; | ||
| 178 | struct uwb_mas_bm mas; | ||
| 179 | bool found = false; | ||
| 180 | 222 | ||
| 181 | /* | 223 | dev_dbg(dev, "backoff_win_increment: window=%d\n", bow->window); |
| 182 | * Search all valid safe allocations until either: too few MAS | ||
| 183 | * are available; or the smallest allocation with sufficient | ||
| 184 | * MAS is found. | ||
| 185 | * | ||
| 186 | * The top of the zones are preferred, so space for larger | ||
| 187 | * allocations is available in the bottom of the zone (e.g., a | ||
| 188 | * 15 MAS allocation should start in row 14 leaving space for | ||
| 189 | * a 120 MAS allocation at row 0). | ||
| 190 | */ | ||
| 191 | for (n = safe_mas_in_row[0]; n >= 1; n--) { | ||
| 192 | int num_mas; | ||
| 193 | 224 | ||
| 194 | num_mas = n * (UWB_NUM_ZONES - 1); | 225 | bow->can_reserve_extra_mases = false; |
| 195 | if (num_mas < rsv->min_mas) | ||
| 196 | break; | ||
| 197 | if (found && num_mas < rsv->max_mas) | ||
| 198 | break; | ||
| 199 | 226 | ||
| 200 | for (r = UWB_MAS_PER_ZONE-1; r >= 0; r--) { | 227 | if((bow->window << 1) == UWB_DRP_BACKOFF_WIN_MAX) |
| 201 | if (safe_mas_in_row[r] < n) | 228 | return; |
| 202 | continue; | ||
| 203 | uwb_rsv_gen_alloc_row(&mas, r, n, 1, UWB_NUM_ZONES); | ||
| 204 | if (uwb_drp_avail_reserve_pending(rsv->rc, &mas) == 0) { | ||
| 205 | found = true; | ||
| 206 | break; | ||
| 207 | } | ||
| 208 | } | ||
| 209 | } | ||
| 210 | 229 | ||
| 211 | if (!found) | 230 | bow->window <<= 1; |
| 212 | return -EBUSY; | 231 | bow->n = random32() & (bow->window - 1); |
| 232 | dev_dbg(dev, "new_window=%d, n=%d\n: ", bow->window, bow->n); | ||
| 213 | 233 | ||
| 214 | bitmap_copy(rsv->mas.bm, mas.bm, UWB_NUM_MAS); | 234 | /* reset the timer associated variables */ |
| 215 | return 0; | 235 | timeout_us = bow->n * UWB_SUPERFRAME_LENGTH_US; |
| 236 | bow->total_expired = 0; | ||
| 237 | mod_timer(&bow->timer, jiffies + usecs_to_jiffies(timeout_us)); | ||
| 216 | } | 238 | } |
| 217 | 239 | ||
| 218 | static void uwb_rsv_stroke_timer(struct uwb_rsv *rsv) | 240 | static void uwb_rsv_stroke_timer(struct uwb_rsv *rsv) |
| @@ -225,13 +247,16 @@ static void uwb_rsv_stroke_timer(struct uwb_rsv *rsv) | |||
| 225 | * received. | 247 | * received. |
| 226 | */ | 248 | */ |
| 227 | if (rsv->is_multicast) { | 249 | if (rsv->is_multicast) { |
| 228 | if (rsv->state == UWB_RSV_STATE_O_INITIATED) | 250 | if (rsv->state == UWB_RSV_STATE_O_INITIATED |
| 251 | || rsv->state == UWB_RSV_STATE_O_MOVE_EXPANDING | ||
| 252 | || rsv->state == UWB_RSV_STATE_O_MOVE_COMBINING | ||
| 253 | || rsv->state == UWB_RSV_STATE_O_MOVE_REDUCING) | ||
| 229 | sframes = 1; | 254 | sframes = 1; |
| 230 | if (rsv->state == UWB_RSV_STATE_O_ESTABLISHED) | 255 | if (rsv->state == UWB_RSV_STATE_O_ESTABLISHED) |
| 231 | sframes = 0; | 256 | sframes = 0; |
| 257 | |||
| 232 | } | 258 | } |
| 233 | 259 | ||
| 234 | rsv->expired = false; | ||
| 235 | if (sframes > 0) { | 260 | if (sframes > 0) { |
| 236 | /* | 261 | /* |
| 237 | * Add an additional 2 superframes to account for the | 262 | * Add an additional 2 superframes to account for the |
| @@ -253,7 +278,7 @@ static void uwb_rsv_state_update(struct uwb_rsv *rsv, | |||
| 253 | rsv->state = new_state; | 278 | rsv->state = new_state; |
| 254 | rsv->ie_valid = false; | 279 | rsv->ie_valid = false; |
| 255 | 280 | ||
| 256 | uwb_rsv_dump(rsv); | 281 | uwb_rsv_dump("SU", rsv); |
| 257 | 282 | ||
| 258 | uwb_rsv_stroke_timer(rsv); | 283 | uwb_rsv_stroke_timer(rsv); |
| 259 | uwb_rsv_sched_update(rsv->rc); | 284 | uwb_rsv_sched_update(rsv->rc); |
| @@ -267,10 +292,17 @@ static void uwb_rsv_callback(struct uwb_rsv *rsv) | |||
| 267 | 292 | ||
| 268 | void uwb_rsv_set_state(struct uwb_rsv *rsv, enum uwb_rsv_state new_state) | 293 | void uwb_rsv_set_state(struct uwb_rsv *rsv, enum uwb_rsv_state new_state) |
| 269 | { | 294 | { |
| 295 | struct uwb_rsv_move *mv = &rsv->mv; | ||
| 296 | |||
| 270 | if (rsv->state == new_state) { | 297 | if (rsv->state == new_state) { |
| 271 | switch (rsv->state) { | 298 | switch (rsv->state) { |
| 272 | case UWB_RSV_STATE_O_ESTABLISHED: | 299 | case UWB_RSV_STATE_O_ESTABLISHED: |
| 300 | case UWB_RSV_STATE_O_MOVE_EXPANDING: | ||
| 301 | case UWB_RSV_STATE_O_MOVE_COMBINING: | ||
| 302 | case UWB_RSV_STATE_O_MOVE_REDUCING: | ||
| 273 | case UWB_RSV_STATE_T_ACCEPTED: | 303 | case UWB_RSV_STATE_T_ACCEPTED: |
| 304 | case UWB_RSV_STATE_T_EXPANDING_ACCEPTED: | ||
| 305 | case UWB_RSV_STATE_T_RESIZED: | ||
| 274 | case UWB_RSV_STATE_NONE: | 306 | case UWB_RSV_STATE_NONE: |
| 275 | uwb_rsv_stroke_timer(rsv); | 307 | uwb_rsv_stroke_timer(rsv); |
| 276 | break; | 308 | break; |
| @@ -282,10 +314,10 @@ void uwb_rsv_set_state(struct uwb_rsv *rsv, enum uwb_rsv_state new_state) | |||
| 282 | return; | 314 | return; |
| 283 | } | 315 | } |
| 284 | 316 | ||
| 317 | uwb_rsv_dump("SC", rsv); | ||
| 318 | |||
| 285 | switch (new_state) { | 319 | switch (new_state) { |
| 286 | case UWB_RSV_STATE_NONE: | 320 | case UWB_RSV_STATE_NONE: |
| 287 | uwb_drp_avail_release(rsv->rc, &rsv->mas); | ||
| 288 | uwb_rsv_put_stream(rsv); | ||
| 289 | uwb_rsv_state_update(rsv, UWB_RSV_STATE_NONE); | 321 | uwb_rsv_state_update(rsv, UWB_RSV_STATE_NONE); |
| 290 | uwb_rsv_callback(rsv); | 322 | uwb_rsv_callback(rsv); |
| 291 | break; | 323 | break; |
| @@ -295,12 +327,45 @@ void uwb_rsv_set_state(struct uwb_rsv *rsv, enum uwb_rsv_state new_state) | |||
| 295 | case UWB_RSV_STATE_O_PENDING: | 327 | case UWB_RSV_STATE_O_PENDING: |
| 296 | uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_PENDING); | 328 | uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_PENDING); |
| 297 | break; | 329 | break; |
| 330 | case UWB_RSV_STATE_O_MODIFIED: | ||
| 331 | /* in the companion there are the MASes to drop */ | ||
| 332 | bitmap_andnot(rsv->mas.bm, rsv->mas.bm, mv->companion_mas.bm, UWB_NUM_MAS); | ||
| 333 | uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_MODIFIED); | ||
| 334 | break; | ||
| 298 | case UWB_RSV_STATE_O_ESTABLISHED: | 335 | case UWB_RSV_STATE_O_ESTABLISHED: |
| 336 | if (rsv->state == UWB_RSV_STATE_O_MODIFIED | ||
| 337 | || rsv->state == UWB_RSV_STATE_O_MOVE_REDUCING) { | ||
| 338 | uwb_drp_avail_release(rsv->rc, &mv->companion_mas); | ||
| 339 | rsv->needs_release_companion_mas = false; | ||
| 340 | } | ||
| 299 | uwb_drp_avail_reserve(rsv->rc, &rsv->mas); | 341 | uwb_drp_avail_reserve(rsv->rc, &rsv->mas); |
| 300 | uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_ESTABLISHED); | 342 | uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_ESTABLISHED); |
| 301 | uwb_rsv_callback(rsv); | 343 | uwb_rsv_callback(rsv); |
| 302 | break; | 344 | break; |
| 345 | case UWB_RSV_STATE_O_MOVE_EXPANDING: | ||
| 346 | rsv->needs_release_companion_mas = true; | ||
| 347 | uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_MOVE_EXPANDING); | ||
| 348 | break; | ||
| 349 | case UWB_RSV_STATE_O_MOVE_COMBINING: | ||
| 350 | rsv->needs_release_companion_mas = false; | ||
| 351 | uwb_drp_avail_reserve(rsv->rc, &mv->companion_mas); | ||
| 352 | bitmap_or(rsv->mas.bm, rsv->mas.bm, mv->companion_mas.bm, UWB_NUM_MAS); | ||
| 353 | rsv->mas.safe += mv->companion_mas.safe; | ||
| 354 | rsv->mas.unsafe += mv->companion_mas.unsafe; | ||
| 355 | uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_MOVE_COMBINING); | ||
| 356 | break; | ||
| 357 | case UWB_RSV_STATE_O_MOVE_REDUCING: | ||
| 358 | bitmap_andnot(mv->companion_mas.bm, rsv->mas.bm, mv->final_mas.bm, UWB_NUM_MAS); | ||
| 359 | rsv->needs_release_companion_mas = true; | ||
| 360 | rsv->mas.safe = mv->final_mas.safe; | ||
| 361 | rsv->mas.unsafe = mv->final_mas.unsafe; | ||
| 362 | bitmap_copy(rsv->mas.bm, mv->final_mas.bm, UWB_NUM_MAS); | ||
| 363 | bitmap_copy(rsv->mas.unsafe_bm, mv->final_mas.unsafe_bm, UWB_NUM_MAS); | ||
| 364 | uwb_rsv_state_update(rsv, UWB_RSV_STATE_O_MOVE_REDUCING); | ||
| 365 | break; | ||
| 303 | case UWB_RSV_STATE_T_ACCEPTED: | 366 | case UWB_RSV_STATE_T_ACCEPTED: |
| 367 | case UWB_RSV_STATE_T_RESIZED: | ||
| 368 | rsv->needs_release_companion_mas = false; | ||
| 304 | uwb_drp_avail_reserve(rsv->rc, &rsv->mas); | 369 | uwb_drp_avail_reserve(rsv->rc, &rsv->mas); |
| 305 | uwb_rsv_state_update(rsv, UWB_RSV_STATE_T_ACCEPTED); | 370 | uwb_rsv_state_update(rsv, UWB_RSV_STATE_T_ACCEPTED); |
| 306 | uwb_rsv_callback(rsv); | 371 | uwb_rsv_callback(rsv); |
| @@ -308,12 +373,82 @@ void uwb_rsv_set_state(struct uwb_rsv *rsv, enum uwb_rsv_state new_state) | |||
| 308 | case UWB_RSV_STATE_T_DENIED: | 373 | case UWB_RSV_STATE_T_DENIED: |
| 309 | uwb_rsv_state_update(rsv, UWB_RSV_STATE_T_DENIED); | 374 | uwb_rsv_state_update(rsv, UWB_RSV_STATE_T_DENIED); |
| 310 | break; | 375 | break; |
| 376 | case UWB_RSV_STATE_T_CONFLICT: | ||
| 377 | uwb_rsv_state_update(rsv, UWB_RSV_STATE_T_CONFLICT); | ||
| 378 | break; | ||
| 379 | case UWB_RSV_STATE_T_PENDING: | ||
| 380 | uwb_rsv_state_update(rsv, UWB_RSV_STATE_T_PENDING); | ||
| 381 | break; | ||
| 382 | case UWB_RSV_STATE_T_EXPANDING_ACCEPTED: | ||
| 383 | rsv->needs_release_companion_mas = true; | ||
| 384 | uwb_drp_avail_reserve(rsv->rc, &mv->companion_mas); | ||
| 385 | uwb_rsv_state_update(rsv, UWB_RSV_STATE_T_EXPANDING_ACCEPTED); | ||
| 386 | break; | ||
| 311 | default: | 387 | default: |
| 312 | dev_err(&rsv->rc->uwb_dev.dev, "unhandled state: %s (%d)\n", | 388 | dev_err(&rsv->rc->uwb_dev.dev, "unhandled state: %s (%d)\n", |
| 313 | uwb_rsv_state_str(new_state), new_state); | 389 | uwb_rsv_state_str(new_state), new_state); |
| 314 | } | 390 | } |
| 315 | } | 391 | } |
| 316 | 392 | ||
| 393 | static void uwb_rsv_handle_timeout_work(struct work_struct *work) | ||
| 394 | { | ||
| 395 | struct uwb_rsv *rsv = container_of(work, struct uwb_rsv, | ||
| 396 | handle_timeout_work); | ||
| 397 | struct uwb_rc *rc = rsv->rc; | ||
| 398 | |||
| 399 | mutex_lock(&rc->rsvs_mutex); | ||
| 400 | |||
| 401 | uwb_rsv_dump("TO", rsv); | ||
| 402 | |||
| 403 | switch (rsv->state) { | ||
| 404 | case UWB_RSV_STATE_O_INITIATED: | ||
| 405 | if (rsv->is_multicast) { | ||
| 406 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_ESTABLISHED); | ||
| 407 | goto unlock; | ||
| 408 | } | ||
| 409 | break; | ||
| 410 | case UWB_RSV_STATE_O_MOVE_EXPANDING: | ||
| 411 | if (rsv->is_multicast) { | ||
| 412 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_MOVE_COMBINING); | ||
| 413 | goto unlock; | ||
| 414 | } | ||
| 415 | break; | ||
| 416 | case UWB_RSV_STATE_O_MOVE_COMBINING: | ||
| 417 | if (rsv->is_multicast) { | ||
| 418 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_MOVE_REDUCING); | ||
| 419 | goto unlock; | ||
| 420 | } | ||
| 421 | break; | ||
| 422 | case UWB_RSV_STATE_O_MOVE_REDUCING: | ||
| 423 | if (rsv->is_multicast) { | ||
| 424 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_ESTABLISHED); | ||
| 425 | goto unlock; | ||
| 426 | } | ||
| 427 | break; | ||
| 428 | case UWB_RSV_STATE_O_ESTABLISHED: | ||
| 429 | if (rsv->is_multicast) | ||
| 430 | goto unlock; | ||
| 431 | break; | ||
| 432 | case UWB_RSV_STATE_T_EXPANDING_ACCEPTED: | ||
| 433 | /* | ||
| 434 | * The time out could be for the main or of the | ||
| 435 | * companion DRP, assume it's for the companion and | ||
| 436 | * drop that first. A further time out is required to | ||
| 437 | * drop the main. | ||
| 438 | */ | ||
| 439 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_T_ACCEPTED); | ||
| 440 | uwb_drp_avail_release(rsv->rc, &rsv->mv.companion_mas); | ||
| 441 | goto unlock; | ||
| 442 | default: | ||
| 443 | break; | ||
| 444 | } | ||
| 445 | |||
| 446 | uwb_rsv_remove(rsv); | ||
| 447 | |||
| 448 | unlock: | ||
| 449 | mutex_unlock(&rc->rsvs_mutex); | ||
| 450 | } | ||
| 451 | |||
| 317 | static struct uwb_rsv *uwb_rsv_alloc(struct uwb_rc *rc) | 452 | static struct uwb_rsv *uwb_rsv_alloc(struct uwb_rc *rc) |
| 318 | { | 453 | { |
| 319 | struct uwb_rsv *rsv; | 454 | struct uwb_rsv *rsv; |
| @@ -324,23 +459,17 @@ static struct uwb_rsv *uwb_rsv_alloc(struct uwb_rc *rc) | |||
| 324 | 459 | ||
| 325 | INIT_LIST_HEAD(&rsv->rc_node); | 460 | INIT_LIST_HEAD(&rsv->rc_node); |
| 326 | INIT_LIST_HEAD(&rsv->pal_node); | 461 | INIT_LIST_HEAD(&rsv->pal_node); |
| 462 | kref_init(&rsv->kref); | ||
| 327 | init_timer(&rsv->timer); | 463 | init_timer(&rsv->timer); |
| 328 | rsv->timer.function = uwb_rsv_timer; | 464 | rsv->timer.function = uwb_rsv_timer; |
| 329 | rsv->timer.data = (unsigned long)rsv; | 465 | rsv->timer.data = (unsigned long)rsv; |
| 330 | 466 | ||
| 331 | rsv->rc = rc; | 467 | rsv->rc = rc; |
| 468 | INIT_WORK(&rsv->handle_timeout_work, uwb_rsv_handle_timeout_work); | ||
| 332 | 469 | ||
| 333 | return rsv; | 470 | return rsv; |
| 334 | } | 471 | } |
| 335 | 472 | ||
| 336 | static void uwb_rsv_free(struct uwb_rsv *rsv) | ||
| 337 | { | ||
| 338 | uwb_dev_put(rsv->owner); | ||
| 339 | if (rsv->target.type == UWB_RSV_TARGET_DEV) | ||
| 340 | uwb_dev_put(rsv->target.dev); | ||
| 341 | kfree(rsv); | ||
| 342 | } | ||
| 343 | |||
| 344 | /** | 473 | /** |
| 345 | * uwb_rsv_create - allocate and initialize a UWB reservation structure | 474 | * uwb_rsv_create - allocate and initialize a UWB reservation structure |
| 346 | * @rc: the radio controller | 475 | * @rc: the radio controller |
| @@ -371,26 +500,36 @@ EXPORT_SYMBOL_GPL(uwb_rsv_create); | |||
| 371 | 500 | ||
| 372 | void uwb_rsv_remove(struct uwb_rsv *rsv) | 501 | void uwb_rsv_remove(struct uwb_rsv *rsv) |
| 373 | { | 502 | { |
| 503 | uwb_rsv_dump("RM", rsv); | ||
| 504 | |||
| 374 | if (rsv->state != UWB_RSV_STATE_NONE) | 505 | if (rsv->state != UWB_RSV_STATE_NONE) |
| 375 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE); | 506 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE); |
| 507 | |||
| 508 | if (rsv->needs_release_companion_mas) | ||
| 509 | uwb_drp_avail_release(rsv->rc, &rsv->mv.companion_mas); | ||
| 510 | uwb_drp_avail_release(rsv->rc, &rsv->mas); | ||
| 511 | |||
| 512 | if (uwb_rsv_is_owner(rsv)) | ||
| 513 | uwb_rsv_put_stream(rsv); | ||
| 514 | |||
| 376 | del_timer_sync(&rsv->timer); | 515 | del_timer_sync(&rsv->timer); |
| 377 | list_del(&rsv->rc_node); | 516 | uwb_dev_put(rsv->owner); |
| 378 | uwb_rsv_free(rsv); | 517 | if (rsv->target.type == UWB_RSV_TARGET_DEV) |
| 518 | uwb_dev_put(rsv->target.dev); | ||
| 519 | |||
| 520 | list_del_init(&rsv->rc_node); | ||
| 521 | uwb_rsv_put(rsv); | ||
| 379 | } | 522 | } |
| 380 | 523 | ||
| 381 | /** | 524 | /** |
| 382 | * uwb_rsv_destroy - free a UWB reservation structure | 525 | * uwb_rsv_destroy - free a UWB reservation structure |
| 383 | * @rsv: the reservation to free | 526 | * @rsv: the reservation to free |
| 384 | * | 527 | * |
| 385 | * The reservation will be terminated if it is pending or established. | 528 | * The reservation must already be terminated. |
| 386 | */ | 529 | */ |
| 387 | void uwb_rsv_destroy(struct uwb_rsv *rsv) | 530 | void uwb_rsv_destroy(struct uwb_rsv *rsv) |
| 388 | { | 531 | { |
| 389 | struct uwb_rc *rc = rsv->rc; | 532 | uwb_rsv_put(rsv); |
| 390 | |||
| 391 | mutex_lock(&rc->rsvs_mutex); | ||
| 392 | uwb_rsv_remove(rsv); | ||
| 393 | mutex_unlock(&rc->rsvs_mutex); | ||
| 394 | } | 533 | } |
| 395 | EXPORT_SYMBOL_GPL(uwb_rsv_destroy); | 534 | EXPORT_SYMBOL_GPL(uwb_rsv_destroy); |
| 396 | 535 | ||
| @@ -399,7 +538,7 @@ EXPORT_SYMBOL_GPL(uwb_rsv_destroy); | |||
| 399 | * @rsv: the reservation | 538 | * @rsv: the reservation |
| 400 | * | 539 | * |
| 401 | * The PAL should fill in @rsv's owner, target, type, max_mas, | 540 | * The PAL should fill in @rsv's owner, target, type, max_mas, |
| 402 | * min_mas, sparsity and is_multicast fields. If the target is a | 541 | * min_mas, max_interval and is_multicast fields. If the target is a |
| 403 | * uwb_dev it must be referenced. | 542 | * uwb_dev it must be referenced. |
| 404 | * | 543 | * |
| 405 | * The reservation's callback will be called when the reservation is | 544 | * The reservation's callback will be called when the reservation is |
| @@ -408,20 +547,32 @@ EXPORT_SYMBOL_GPL(uwb_rsv_destroy); | |||
| 408 | int uwb_rsv_establish(struct uwb_rsv *rsv) | 547 | int uwb_rsv_establish(struct uwb_rsv *rsv) |
| 409 | { | 548 | { |
| 410 | struct uwb_rc *rc = rsv->rc; | 549 | struct uwb_rc *rc = rsv->rc; |
| 550 | struct uwb_mas_bm available; | ||
| 411 | int ret; | 551 | int ret; |
| 412 | 552 | ||
| 413 | mutex_lock(&rc->rsvs_mutex); | 553 | mutex_lock(&rc->rsvs_mutex); |
| 414 | |||
| 415 | ret = uwb_rsv_get_stream(rsv); | 554 | ret = uwb_rsv_get_stream(rsv); |
| 416 | if (ret) | 555 | if (ret) |
| 417 | goto out; | 556 | goto out; |
| 418 | 557 | ||
| 419 | ret = uwb_rsv_alloc_mas(rsv); | 558 | rsv->tiebreaker = random32() & 1; |
| 420 | if (ret) { | 559 | /* get available mas bitmap */ |
| 560 | uwb_drp_available(rc, &available); | ||
| 561 | |||
| 562 | ret = uwb_rsv_find_best_allocation(rsv, &available, &rsv->mas); | ||
| 563 | if (ret == UWB_RSV_ALLOC_NOT_FOUND) { | ||
| 564 | ret = -EBUSY; | ||
| 565 | uwb_rsv_put_stream(rsv); | ||
| 566 | goto out; | ||
| 567 | } | ||
| 568 | |||
| 569 | ret = uwb_drp_avail_reserve_pending(rc, &rsv->mas); | ||
| 570 | if (ret != 0) { | ||
| 421 | uwb_rsv_put_stream(rsv); | 571 | uwb_rsv_put_stream(rsv); |
| 422 | goto out; | 572 | goto out; |
| 423 | } | 573 | } |
| 424 | 574 | ||
| 575 | uwb_rsv_get(rsv); | ||
| 425 | list_add_tail(&rsv->rc_node, &rc->reservations); | 576 | list_add_tail(&rsv->rc_node, &rc->reservations); |
| 426 | rsv->owner = &rc->uwb_dev; | 577 | rsv->owner = &rc->uwb_dev; |
| 427 | uwb_dev_get(rsv->owner); | 578 | uwb_dev_get(rsv->owner); |
| @@ -437,16 +588,71 @@ EXPORT_SYMBOL_GPL(uwb_rsv_establish); | |||
| 437 | * @rsv: the reservation to modify | 588 | * @rsv: the reservation to modify |
| 438 | * @max_mas: new maximum MAS to reserve | 589 | * @max_mas: new maximum MAS to reserve |
| 439 | * @min_mas: new minimum MAS to reserve | 590 | * @min_mas: new minimum MAS to reserve |
| 440 | * @sparsity: new sparsity to use | 591 | * @max_interval: new max_interval to use |
| 441 | * | 592 | * |
| 442 | * FIXME: implement this once there are PALs that use it. | 593 | * FIXME: implement this once there are PALs that use it. |
| 443 | */ | 594 | */ |
| 444 | int uwb_rsv_modify(struct uwb_rsv *rsv, int max_mas, int min_mas, int sparsity) | 595 | int uwb_rsv_modify(struct uwb_rsv *rsv, int max_mas, int min_mas, int max_interval) |
| 445 | { | 596 | { |
| 446 | return -ENOSYS; | 597 | return -ENOSYS; |
| 447 | } | 598 | } |
| 448 | EXPORT_SYMBOL_GPL(uwb_rsv_modify); | 599 | EXPORT_SYMBOL_GPL(uwb_rsv_modify); |
| 449 | 600 | ||
| 601 | /* | ||
| 602 | * move an already established reservation (rc->rsvs_mutex must to be | ||
| 603 | * taken when tis function is called) | ||
| 604 | */ | ||
| 605 | int uwb_rsv_try_move(struct uwb_rsv *rsv, struct uwb_mas_bm *available) | ||
| 606 | { | ||
| 607 | struct uwb_rc *rc = rsv->rc; | ||
| 608 | struct uwb_drp_backoff_win *bow = &rc->bow; | ||
| 609 | struct device *dev = &rc->uwb_dev.dev; | ||
| 610 | struct uwb_rsv_move *mv; | ||
| 611 | int ret = 0; | ||
| 612 | |||
| 613 | if (bow->can_reserve_extra_mases == false) | ||
| 614 | return -EBUSY; | ||
| 615 | |||
| 616 | mv = &rsv->mv; | ||
| 617 | |||
| 618 | if (uwb_rsv_find_best_allocation(rsv, available, &mv->final_mas) == UWB_RSV_ALLOC_FOUND) { | ||
| 619 | |||
| 620 | if (!bitmap_equal(rsv->mas.bm, mv->final_mas.bm, UWB_NUM_MAS)) { | ||
| 621 | /* We want to move the reservation */ | ||
| 622 | bitmap_andnot(mv->companion_mas.bm, mv->final_mas.bm, rsv->mas.bm, UWB_NUM_MAS); | ||
| 623 | uwb_drp_avail_reserve_pending(rc, &mv->companion_mas); | ||
| 624 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_O_MOVE_EXPANDING); | ||
| 625 | } | ||
| 626 | } else { | ||
| 627 | dev_dbg(dev, "new allocation not found\n"); | ||
| 628 | } | ||
| 629 | |||
| 630 | return ret; | ||
| 631 | } | ||
| 632 | |||
| 633 | /* It will try to move every reservation in state O_ESTABLISHED giving | ||
| 634 | * to the MAS allocator algorithm an availability that is the real one | ||
| 635 | * plus the allocation already established from the reservation. */ | ||
| 636 | void uwb_rsv_handle_drp_avail_change(struct uwb_rc *rc) | ||
| 637 | { | ||
| 638 | struct uwb_drp_backoff_win *bow = &rc->bow; | ||
| 639 | struct uwb_rsv *rsv; | ||
| 640 | struct uwb_mas_bm mas; | ||
| 641 | |||
| 642 | if (bow->can_reserve_extra_mases == false) | ||
| 643 | return; | ||
| 644 | |||
| 645 | list_for_each_entry(rsv, &rc->reservations, rc_node) { | ||
| 646 | if (rsv->state == UWB_RSV_STATE_O_ESTABLISHED || | ||
| 647 | rsv->state == UWB_RSV_STATE_O_TO_BE_MOVED) { | ||
| 648 | uwb_drp_available(rc, &mas); | ||
| 649 | bitmap_or(mas.bm, mas.bm, rsv->mas.bm, UWB_NUM_MAS); | ||
| 650 | uwb_rsv_try_move(rsv, &mas); | ||
| 651 | } | ||
| 652 | } | ||
| 653 | |||
| 654 | } | ||
| 655 | |||
| 450 | /** | 656 | /** |
| 451 | * uwb_rsv_terminate - terminate an established reservation | 657 | * uwb_rsv_terminate - terminate an established reservation |
| 452 | * @rsv: the reservation to terminate | 658 | * @rsv: the reservation to terminate |
| @@ -463,7 +669,8 @@ void uwb_rsv_terminate(struct uwb_rsv *rsv) | |||
| 463 | 669 | ||
| 464 | mutex_lock(&rc->rsvs_mutex); | 670 | mutex_lock(&rc->rsvs_mutex); |
| 465 | 671 | ||
| 466 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE); | 672 | if (rsv->state != UWB_RSV_STATE_NONE) |
| 673 | uwb_rsv_set_state(rsv, UWB_RSV_STATE_NONE); | ||
| 467 | 674 | ||
| 468 | mutex_unlock(&rc->rsvs_mutex); | 675 | mutex_unlock(&rc->rsvs_mutex); |
| 469 | } | 676 | } |
| @@ -477,9 +684,14 @@ EXPORT_SYMBOL_GPL(uwb_rsv_terminate); | |||
| 477 | * | 684 | * |
| 478 | * Reservation requests from peers are denied unless a PAL accepts it | 685 | * Reservation requests from peers are denied unless a PAL accepts it |
| 479 | * by calling this function. | 686 | * by calling this function. |
| 687 | * | ||
| 688 | * The PAL call uwb_rsv_destroy() for all accepted reservations before | ||
| 689 | * calling uwb_pal_unregister(). | ||
| 480 | */ | 690 | */ |
| 481 | void uwb_rsv_accept(struct uwb_rsv *rsv, uwb_rsv_cb_f cb, void *pal_priv) | 691 | void uwb_rsv_accept(struct uwb_rsv *rsv, uwb_rsv_cb_f cb, void *pal_priv) |
| 482 | { | 692 | { |
| 693 | uwb_rsv_get(rsv); | ||
| 694 | |||
| 483 | rsv->callback = cb; | 695 | rsv->callback = cb; |
| 484 | rsv->pal_priv = pal_priv; | 696 | rsv->pal_priv = pal_priv; |
| 485 | rsv->state = UWB_RSV_STATE_T_ACCEPTED; | 697 | rsv->state = UWB_RSV_STATE_T_ACCEPTED; |
| @@ -530,9 +742,9 @@ static struct uwb_rsv *uwb_rsv_new_target(struct uwb_rc *rc, | |||
| 530 | uwb_dev_get(rsv->owner); | 742 | uwb_dev_get(rsv->owner); |
| 531 | rsv->target.type = UWB_RSV_TARGET_DEV; | 743 | rsv->target.type = UWB_RSV_TARGET_DEV; |
| 532 | rsv->target.dev = &rc->uwb_dev; | 744 | rsv->target.dev = &rc->uwb_dev; |
| 745 | uwb_dev_get(&rc->uwb_dev); | ||
| 533 | rsv->type = uwb_ie_drp_type(drp_ie); | 746 | rsv->type = uwb_ie_drp_type(drp_ie); |
| 534 | rsv->stream = uwb_ie_drp_stream_index(drp_ie); | 747 | rsv->stream = uwb_ie_drp_stream_index(drp_ie); |
| 535 | set_bit(rsv->stream, rsv->owner->streams); | ||
| 536 | uwb_drp_ie_to_bm(&rsv->mas, drp_ie); | 748 | uwb_drp_ie_to_bm(&rsv->mas, drp_ie); |
| 537 | 749 | ||
| 538 | /* | 750 | /* |
| @@ -540,24 +752,46 @@ static struct uwb_rsv *uwb_rsv_new_target(struct uwb_rc *rc, | |||
| 540 | * deny the request. | 752 | * deny the request. |
| 541 | */ | 753 | */ |
| 542 | rsv->state = UWB_RSV_STATE_T_DENIED; | 754 | rsv->state = UWB_RSV_STATE_T_DENIED; |
| 543 | spin_lock(&rc->pal_lock); | 755 | mutex_lock(&rc->uwb_dev.mutex); |
| 544 | list_for_each_entry(pal, &rc->pals, node) { | 756 | list_for_each_entry(pal, &rc->pals, node) { |
| 545 | if (pal->new_rsv) | 757 | if (pal->new_rsv) |
| 546 | pal->new_rsv(rsv); | 758 | pal->new_rsv(pal, rsv); |
| 547 | if (rsv->state == UWB_RSV_STATE_T_ACCEPTED) | 759 | if (rsv->state == UWB_RSV_STATE_T_ACCEPTED) |
| 548 | break; | 760 | break; |
| 549 | } | 761 | } |
| 550 | spin_unlock(&rc->pal_lock); | 762 | mutex_unlock(&rc->uwb_dev.mutex); |
| 551 | 763 | ||
| 552 | list_add_tail(&rsv->rc_node, &rc->reservations); | 764 | list_add_tail(&rsv->rc_node, &rc->reservations); |
| 553 | state = rsv->state; | 765 | state = rsv->state; |
| 554 | rsv->state = UWB_RSV_STATE_NONE; | 766 | rsv->state = UWB_RSV_STATE_NONE; |
| 555 | uwb_rsv_set_state(rsv, state); | 767 | |
| 768 | /* FIXME: do something sensible here */ | ||
| 769 | if (state == UWB_RSV_STATE_T_ACCEPTED | ||
| 770 | && uwb_drp_avail_reserve_pending(rc, &rsv->mas) == -EBUSY) { | ||
| 771 | /* FIXME: do something sensible here */ | ||
| 772 | } else { | ||
| 773 | uwb_rsv_set_state(rsv, state); | ||
| 774 | } | ||
| 556 | 775 | ||
| 557 | return rsv; | 776 | return rsv; |
| 558 | } | 777 | } |
| 559 | 778 | ||
| 560 | /** | 779 | /** |
| 780 | * uwb_rsv_get_usable_mas - get the bitmap of the usable MAS of a reservations | ||
| 781 | * @rsv: the reservation. | ||
| 782 | * @mas: returns the available MAS. | ||
| 783 | * | ||
| 784 | * The usable MAS of a reservation may be less than the negotiated MAS | ||
| 785 | * if alien BPs are present. | ||
| 786 | */ | ||
| 787 | void uwb_rsv_get_usable_mas(struct uwb_rsv *rsv, struct uwb_mas_bm *mas) | ||
| 788 | { | ||
| 789 | bitmap_zero(mas->bm, UWB_NUM_MAS); | ||
| 790 | bitmap_andnot(mas->bm, rsv->mas.bm, rsv->rc->cnflt_alien_bitmap.bm, UWB_NUM_MAS); | ||
| 791 | } | ||
| 792 | EXPORT_SYMBOL_GPL(uwb_rsv_get_usable_mas); | ||
| 793 | |||
| 794 | /** | ||
| 561 | * uwb_rsv_find - find a reservation for a received DRP IE. | 795 | * uwb_rsv_find - find a reservation for a received DRP IE. |
| 562 | * @rc: the radio controller | 796 | * @rc: the radio controller |
| 563 | * @src: source of the DRP IE | 797 | * @src: source of the DRP IE |
| @@ -596,8 +830,6 @@ static bool uwb_rsv_update_all(struct uwb_rc *rc) | |||
| 596 | bool ie_updated = false; | 830 | bool ie_updated = false; |
| 597 | 831 | ||
| 598 | list_for_each_entry_safe(rsv, t, &rc->reservations, rc_node) { | 832 | list_for_each_entry_safe(rsv, t, &rc->reservations, rc_node) { |
| 599 | if (rsv->expired) | ||
| 600 | uwb_drp_handle_timeout(rsv); | ||
| 601 | if (!rsv->ie_valid) { | 833 | if (!rsv->ie_valid) { |
| 602 | uwb_drp_ie_update(rsv); | 834 | uwb_drp_ie_update(rsv); |
| 603 | ie_updated = true; | 835 | ie_updated = true; |
| @@ -607,9 +839,47 @@ static bool uwb_rsv_update_all(struct uwb_rc *rc) | |||
| 607 | return ie_updated; | 839 | return ie_updated; |
| 608 | } | 840 | } |
| 609 | 841 | ||
| 842 | void uwb_rsv_queue_update(struct uwb_rc *rc) | ||
| 843 | { | ||
| 844 | unsigned long delay_us = UWB_MAS_LENGTH_US * UWB_MAS_PER_ZONE; | ||
| 845 | |||
| 846 | queue_delayed_work(rc->rsv_workq, &rc->rsv_update_work, usecs_to_jiffies(delay_us)); | ||
| 847 | } | ||
| 848 | |||
| 849 | /** | ||
| 850 | * uwb_rsv_sched_update - schedule an update of the DRP IEs | ||
| 851 | * @rc: the radio controller. | ||
| 852 | * | ||
| 853 | * To improve performance and ensure correctness with [ECMA-368] the | ||
| 854 | * number of SET-DRP-IE commands that are done are limited. | ||
| 855 | * | ||
| 856 | * DRP IEs update come from two sources: DRP events from the hardware | ||
| 857 | * which all occur at the beginning of the superframe ('syncronous' | ||
| 858 | * events) and reservation establishment/termination requests from | ||
| 859 | * PALs or timers ('asynchronous' events). | ||
| 860 | * | ||
| 861 | * A delayed work ensures that all the synchronous events result in | ||
| 862 | * one SET-DRP-IE command. | ||
| 863 | * | ||
| 864 | * Additional logic (the set_drp_ie_pending and rsv_updated_postponed | ||
| 865 | * flags) will prevent an asynchrous event starting a SET-DRP-IE | ||
| 866 | * command if one is currently awaiting a response. | ||
| 867 | * | ||
| 868 | * FIXME: this does leave a window where an asynchrous event can delay | ||
| 869 | * the SET-DRP-IE for a synchronous event by one superframe. | ||
| 870 | */ | ||
| 610 | void uwb_rsv_sched_update(struct uwb_rc *rc) | 871 | void uwb_rsv_sched_update(struct uwb_rc *rc) |
| 611 | { | 872 | { |
| 612 | queue_work(rc->rsv_workq, &rc->rsv_update_work); | 873 | spin_lock(&rc->rsvs_lock); |
| 874 | if (!delayed_work_pending(&rc->rsv_update_work)) { | ||
| 875 | if (rc->set_drp_ie_pending > 0) { | ||
| 876 | rc->set_drp_ie_pending++; | ||
| 877 | goto unlock; | ||
| 878 | } | ||
| 879 | uwb_rsv_queue_update(rc); | ||
| 880 | } | ||
| 881 | unlock: | ||
| 882 | spin_unlock(&rc->rsvs_lock); | ||
| 613 | } | 883 | } |
| 614 | 884 | ||
| 615 | /* | 885 | /* |
| @@ -618,7 +888,8 @@ void uwb_rsv_sched_update(struct uwb_rc *rc) | |||
| 618 | */ | 888 | */ |
| 619 | static void uwb_rsv_update_work(struct work_struct *work) | 889 | static void uwb_rsv_update_work(struct work_struct *work) |
| 620 | { | 890 | { |
| 621 | struct uwb_rc *rc = container_of(work, struct uwb_rc, rsv_update_work); | 891 | struct uwb_rc *rc = container_of(work, struct uwb_rc, |
| 892 | rsv_update_work.work); | ||
| 622 | bool ie_updated; | 893 | bool ie_updated; |
| 623 | 894 | ||
| 624 | mutex_lock(&rc->rsvs_mutex); | 895 | mutex_lock(&rc->rsvs_mutex); |
| @@ -630,25 +901,71 @@ static void uwb_rsv_update_work(struct work_struct *work) | |||
| 630 | ie_updated = true; | 901 | ie_updated = true; |
| 631 | } | 902 | } |
| 632 | 903 | ||
| 633 | if (ie_updated) | 904 | if (ie_updated && (rc->set_drp_ie_pending == 0)) |
| 634 | uwb_rc_send_all_drp_ie(rc); | 905 | uwb_rc_send_all_drp_ie(rc); |
| 635 | 906 | ||
| 636 | mutex_unlock(&rc->rsvs_mutex); | 907 | mutex_unlock(&rc->rsvs_mutex); |
| 637 | } | 908 | } |
| 638 | 909 | ||
| 910 | static void uwb_rsv_alien_bp_work(struct work_struct *work) | ||
| 911 | { | ||
| 912 | struct uwb_rc *rc = container_of(work, struct uwb_rc, | ||
| 913 | rsv_alien_bp_work.work); | ||
| 914 | struct uwb_rsv *rsv; | ||
| 915 | |||
| 916 | mutex_lock(&rc->rsvs_mutex); | ||
| 917 | |||
| 918 | list_for_each_entry(rsv, &rc->reservations, rc_node) { | ||
| 919 | if (rsv->type != UWB_DRP_TYPE_ALIEN_BP) { | ||
| 920 | rsv->callback(rsv); | ||
| 921 | } | ||
| 922 | } | ||
| 923 | |||
| 924 | mutex_unlock(&rc->rsvs_mutex); | ||
| 925 | } | ||
| 926 | |||
| 639 | static void uwb_rsv_timer(unsigned long arg) | 927 | static void uwb_rsv_timer(unsigned long arg) |
| 640 | { | 928 | { |
| 641 | struct uwb_rsv *rsv = (struct uwb_rsv *)arg; | 929 | struct uwb_rsv *rsv = (struct uwb_rsv *)arg; |
| 642 | 930 | ||
| 643 | rsv->expired = true; | 931 | queue_work(rsv->rc->rsv_workq, &rsv->handle_timeout_work); |
| 644 | uwb_rsv_sched_update(rsv->rc); | 932 | } |
| 933 | |||
| 934 | /** | ||
| 935 | * uwb_rsv_remove_all - remove all reservations | ||
| 936 | * @rc: the radio controller | ||
| 937 | * | ||
| 938 | * A DRP IE update is not done. | ||
| 939 | */ | ||
| 940 | void uwb_rsv_remove_all(struct uwb_rc *rc) | ||
| 941 | { | ||
| 942 | struct uwb_rsv *rsv, *t; | ||
| 943 | |||
| 944 | mutex_lock(&rc->rsvs_mutex); | ||
| 945 | list_for_each_entry_safe(rsv, t, &rc->reservations, rc_node) { | ||
| 946 | uwb_rsv_remove(rsv); | ||
| 947 | } | ||
| 948 | /* Cancel any postponed update. */ | ||
| 949 | rc->set_drp_ie_pending = 0; | ||
| 950 | mutex_unlock(&rc->rsvs_mutex); | ||
| 951 | |||
| 952 | cancel_delayed_work_sync(&rc->rsv_update_work); | ||
| 645 | } | 953 | } |
| 646 | 954 | ||
| 647 | void uwb_rsv_init(struct uwb_rc *rc) | 955 | void uwb_rsv_init(struct uwb_rc *rc) |
| 648 | { | 956 | { |
| 649 | INIT_LIST_HEAD(&rc->reservations); | 957 | INIT_LIST_HEAD(&rc->reservations); |
| 958 | INIT_LIST_HEAD(&rc->cnflt_alien_list); | ||
| 650 | mutex_init(&rc->rsvs_mutex); | 959 | mutex_init(&rc->rsvs_mutex); |
| 651 | INIT_WORK(&rc->rsv_update_work, uwb_rsv_update_work); | 960 | spin_lock_init(&rc->rsvs_lock); |
| 961 | INIT_DELAYED_WORK(&rc->rsv_update_work, uwb_rsv_update_work); | ||
| 962 | INIT_DELAYED_WORK(&rc->rsv_alien_bp_work, uwb_rsv_alien_bp_work); | ||
| 963 | rc->bow.can_reserve_extra_mases = true; | ||
| 964 | rc->bow.total_expired = 0; | ||
| 965 | rc->bow.window = UWB_DRP_BACKOFF_WIN_MIN >> 1; | ||
| 966 | init_timer(&rc->bow.timer); | ||
| 967 | rc->bow.timer.function = uwb_rsv_backoff_win_timer; | ||
| 968 | rc->bow.timer.data = (unsigned long)&rc->bow; | ||
| 652 | 969 | ||
| 653 | bitmap_complement(rc->uwb_dev.streams, rc->uwb_dev.streams, UWB_NUM_STREAMS); | 970 | bitmap_complement(rc->uwb_dev.streams, rc->uwb_dev.streams, UWB_NUM_STREAMS); |
| 654 | } | 971 | } |
| @@ -667,14 +984,6 @@ int uwb_rsv_setup(struct uwb_rc *rc) | |||
| 667 | 984 | ||
| 668 | void uwb_rsv_cleanup(struct uwb_rc *rc) | 985 | void uwb_rsv_cleanup(struct uwb_rc *rc) |
| 669 | { | 986 | { |
| 670 | struct uwb_rsv *rsv, *t; | 987 | uwb_rsv_remove_all(rc); |
| 671 | |||
| 672 | mutex_lock(&rc->rsvs_mutex); | ||
| 673 | list_for_each_entry_safe(rsv, t, &rc->reservations, rc_node) { | ||
| 674 | uwb_rsv_remove(rsv); | ||
| 675 | } | ||
| 676 | mutex_unlock(&rc->rsvs_mutex); | ||
| 677 | |||
| 678 | cancel_work_sync(&rc->rsv_update_work); | ||
| 679 | destroy_workqueue(rc->rsv_workq); | 988 | destroy_workqueue(rc->rsv_workq); |
| 680 | } | 989 | } |
diff --git a/drivers/uwb/umc-bus.c b/drivers/uwb/umc-bus.c index 2d8d62d9f53..5ad36164c13 100644 --- a/drivers/uwb/umc-bus.c +++ b/drivers/uwb/umc-bus.c | |||
| @@ -11,23 +11,48 @@ | |||
| 11 | #include <linux/uwb/umc.h> | 11 | #include <linux/uwb/umc.h> |
| 12 | #include <linux/pci.h> | 12 | #include <linux/pci.h> |
| 13 | 13 | ||
| 14 | static int umc_bus_unbind_helper(struct device *dev, void *data) | 14 | static int umc_bus_pre_reset_helper(struct device *dev, void *data) |
| 15 | { | 15 | { |
| 16 | struct device *parent = data; | 16 | int ret = 0; |
| 17 | 17 | ||
| 18 | if (dev->parent == parent && dev->driver) | 18 | if (dev->driver) { |
| 19 | device_release_driver(dev); | 19 | struct umc_dev *umc = to_umc_dev(dev); |
| 20 | return 0; | 20 | struct umc_driver *umc_drv = to_umc_driver(dev->driver); |
| 21 | |||
| 22 | if (umc_drv->pre_reset) | ||
| 23 | ret = umc_drv->pre_reset(umc); | ||
| 24 | else | ||
| 25 | device_release_driver(dev); | ||
| 26 | } | ||
| 27 | return ret; | ||
| 28 | } | ||
| 29 | |||
| 30 | static int umc_bus_post_reset_helper(struct device *dev, void *data) | ||
| 31 | { | ||
| 32 | int ret = 0; | ||
| 33 | |||
| 34 | if (dev->driver) { | ||
| 35 | struct umc_dev *umc = to_umc_dev(dev); | ||
| 36 | struct umc_driver *umc_drv = to_umc_driver(dev->driver); | ||
| 37 | |||
| 38 | if (umc_drv->post_reset) | ||
| 39 | ret = umc_drv->post_reset(umc); | ||
| 40 | } else | ||
| 41 | ret = device_attach(dev); | ||
| 42 | |||
| 43 | return ret; | ||
| 21 | } | 44 | } |
| 22 | 45 | ||
| 23 | /** | 46 | /** |
| 24 | * umc_controller_reset - reset the whole UMC controller | 47 | * umc_controller_reset - reset the whole UMC controller |
| 25 | * @umc: the UMC device for the radio controller. | 48 | * @umc: the UMC device for the radio controller. |
| 26 | * | 49 | * |
| 27 | * Drivers will be unbound from all UMC devices belonging to the | 50 | * Drivers or all capabilities of the controller will have their |
| 28 | * controller and then the radio controller will be rebound. The | 51 | * pre_reset methods called or be unbound from their device. Then all |
| 29 | * radio controller is expected to do a full hardware reset when it is | 52 | * post_reset methods will be called or the drivers will be rebound. |
| 30 | * probed. | 53 | * |
| 54 | * Radio controllers must provide pre_reset and post_reset methods and | ||
| 55 | * reset the hardware in their start method. | ||
| 31 | * | 56 | * |
| 32 | * If this is called while a probe() or remove() is in progress it | 57 | * If this is called while a probe() or remove() is in progress it |
| 33 | * will return -EAGAIN and not perform the reset. | 58 | * will return -EAGAIN and not perform the reset. |
| @@ -35,14 +60,13 @@ static int umc_bus_unbind_helper(struct device *dev, void *data) | |||
| 35 | int umc_controller_reset(struct umc_dev *umc) | 60 | int umc_controller_reset(struct umc_dev *umc) |
| 36 | { | 61 | { |
| 37 | struct device *parent = umc->dev.parent; | 62 | struct device *parent = umc->dev.parent; |
| 38 | int ret; | 63 | int ret = 0; |
| 39 | 64 | ||
| 40 | if (down_trylock(&parent->sem)) | 65 | if(down_trylock(&parent->sem)) |
| 41 | return -EAGAIN; | 66 | return -EAGAIN; |
| 42 | bus_for_each_dev(&umc_bus_type, NULL, parent, umc_bus_unbind_helper); | 67 | ret = device_for_each_child(parent, parent, umc_bus_pre_reset_helper); |
| 43 | ret = device_attach(&umc->dev); | 68 | if (ret >= 0) |
| 44 | if (ret == 1) | 69 | device_for_each_child(parent, parent, umc_bus_post_reset_helper); |
| 45 | ret = 0; | ||
| 46 | up(&parent->sem); | 70 | up(&parent->sem); |
| 47 | 71 | ||
| 48 | return ret; | 72 | return ret; |
| @@ -75,10 +99,10 @@ static int umc_bus_rescan_helper(struct device *dev, void *data) | |||
| 75 | if (!dev->driver) | 99 | if (!dev->driver) |
| 76 | ret = device_attach(dev); | 100 | ret = device_attach(dev); |
| 77 | 101 | ||
| 78 | return ret < 0 ? ret : 0; | 102 | return ret; |
| 79 | } | 103 | } |
| 80 | 104 | ||
| 81 | static void umc_bus_rescan(void) | 105 | static void umc_bus_rescan(struct device *parent) |
| 82 | { | 106 | { |
| 83 | int err; | 107 | int err; |
| 84 | 108 | ||
| @@ -86,7 +110,7 @@ static void umc_bus_rescan(void) | |||
| 86 | * We can't use bus_rescan_devices() here as it deadlocks when | 110 | * We can't use bus_rescan_devices() here as it deadlocks when |
| 87 | * it tries to retake the dev->parent semaphore. | 111 | * it tries to retake the dev->parent semaphore. |
| 88 | */ | 112 | */ |
| 89 | err = bus_for_each_dev(&umc_bus_type, NULL, NULL, umc_bus_rescan_helper); | 113 | err = device_for_each_child(parent, NULL, umc_bus_rescan_helper); |
| 90 | if (err < 0) | 114 | if (err < 0) |
| 91 | printk(KERN_WARNING "%s: rescan of bus failed: %d\n", | 115 | printk(KERN_WARNING "%s: rescan of bus failed: %d\n", |
| 92 | KBUILD_MODNAME, err); | 116 | KBUILD_MODNAME, err); |
| @@ -120,7 +144,7 @@ static int umc_device_probe(struct device *dev) | |||
| 120 | if (err) | 144 | if (err) |
| 121 | put_device(dev); | 145 | put_device(dev); |
| 122 | else | 146 | else |
| 123 | umc_bus_rescan(); | 147 | umc_bus_rescan(dev->parent); |
| 124 | 148 | ||
| 125 | return err; | 149 | return err; |
| 126 | } | 150 | } |
diff --git a/drivers/uwb/umc-dev.c b/drivers/uwb/umc-dev.c index aa44e1c1a10..1fc7d8270bb 100644 --- a/drivers/uwb/umc-dev.c +++ b/drivers/uwb/umc-dev.c | |||
| @@ -7,8 +7,6 @@ | |||
| 7 | */ | 7 | */ |
| 8 | #include <linux/kernel.h> | 8 | #include <linux/kernel.h> |
| 9 | #include <linux/uwb/umc.h> | 9 | #include <linux/uwb/umc.h> |
| 10 | #define D_LOCAL 0 | ||
| 11 | #include <linux/uwb/debug.h> | ||
| 12 | 10 | ||
| 13 | static void umc_device_release(struct device *dev) | 11 | static void umc_device_release(struct device *dev) |
| 14 | { | 12 | { |
| @@ -31,8 +29,7 @@ struct umc_dev *umc_device_create(struct device *parent, int n) | |||
| 31 | 29 | ||
| 32 | umc = kzalloc(sizeof(struct umc_dev), GFP_KERNEL); | 30 | umc = kzalloc(sizeof(struct umc_dev), GFP_KERNEL); |
| 33 | if (umc) { | 31 | if (umc) { |
| 34 | snprintf(umc->dev.bus_id, sizeof(umc->dev.bus_id), "%s-%d", | 32 | dev_set_name(&umc->dev, "%s-%d", dev_name(parent), n); |
| 35 | parent->bus_id, n); | ||
| 36 | umc->dev.parent = parent; | 33 | umc->dev.parent = parent; |
| 37 | umc->dev.bus = &umc_bus_type; | 34 | umc->dev.bus = &umc_bus_type; |
| 38 | umc->dev.release = umc_device_release; | 35 | umc->dev.release = umc_device_release; |
| @@ -54,8 +51,6 @@ int umc_device_register(struct umc_dev *umc) | |||
| 54 | { | 51 | { |
| 55 | int err; | 52 | int err; |
| 56 | 53 | ||
| 57 | d_fnstart(3, &umc->dev, "(umc_dev %p)\n", umc); | ||
| 58 | |||
| 59 | err = request_resource(umc->resource.parent, &umc->resource); | 54 | err = request_resource(umc->resource.parent, &umc->resource); |
| 60 | if (err < 0) { | 55 | if (err < 0) { |
| 61 | dev_err(&umc->dev, "can't allocate resource range " | 56 | dev_err(&umc->dev, "can't allocate resource range " |
| @@ -69,13 +64,11 @@ int umc_device_register(struct umc_dev *umc) | |||
| 69 | err = device_register(&umc->dev); | 64 | err = device_register(&umc->dev); |
| 70 | if (err < 0) | 65 | if (err < 0) |
| 71 | goto error_device_register; | 66 | goto error_device_register; |
| 72 | d_fnend(3, &umc->dev, "(umc_dev %p) = 0\n", umc); | ||
| 73 | return 0; | 67 | return 0; |
| 74 | 68 | ||
| 75 | error_device_register: | 69 | error_device_register: |
| 76 | release_resource(&umc->resource); | 70 | release_resource(&umc->resource); |
| 77 | error_request_resource: | 71 | error_request_resource: |
| 78 | d_fnend(3, &umc->dev, "(umc_dev %p) = %d\n", umc, err); | ||
| 79 | return err; | 72 | return err; |
| 80 | } | 73 | } |
| 81 | EXPORT_SYMBOL_GPL(umc_device_register); | 74 | EXPORT_SYMBOL_GPL(umc_device_register); |
| @@ -95,10 +88,8 @@ void umc_device_unregister(struct umc_dev *umc) | |||
| 95 | if (!umc) | 88 | if (!umc) |
| 96 | return; | 89 | return; |
| 97 | dev = get_device(&umc->dev); | 90 | dev = get_device(&umc->dev); |
| 98 | d_fnstart(3, dev, "(umc_dev %p)\n", umc); | ||
| 99 | device_unregister(&umc->dev); | 91 | device_unregister(&umc->dev); |
| 100 | release_resource(&umc->resource); | 92 | release_resource(&umc->resource); |
| 101 | d_fnend(3, dev, "(umc_dev %p) = void\n", umc); | ||
| 102 | put_device(dev); | 93 | put_device(dev); |
| 103 | } | 94 | } |
| 104 | EXPORT_SYMBOL_GPL(umc_device_unregister); | 95 | EXPORT_SYMBOL_GPL(umc_device_unregister); |
diff --git a/drivers/uwb/uwb-debug.c b/drivers/uwb/uwb-debug.c index 6d232c35d07..4a42993700c 100644 --- a/drivers/uwb/uwb-debug.c +++ b/drivers/uwb/uwb-debug.c | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | * | 4 | * |
| 5 | * Copyright (C) 2005-2006 Intel Corporation | 5 | * Copyright (C) 2005-2006 Intel Corporation |
| 6 | * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> | 6 | * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> |
| 7 | * Copyright (C) 2008 Cambridge Silicon Radio Ltd. | ||
| 7 | * | 8 | * |
| 8 | * This program is free software; you can redistribute it and/or | 9 | * This program is free software; you can redistribute it and/or |
| 9 | * modify it under the terms of the GNU General Public License version | 10 | * modify it under the terms of the GNU General Public License version |
| @@ -33,31 +34,9 @@ | |||
| 33 | #include <linux/seq_file.h> | 34 | #include <linux/seq_file.h> |
| 34 | 35 | ||
| 35 | #include <linux/uwb/debug-cmd.h> | 36 | #include <linux/uwb/debug-cmd.h> |
| 36 | #define D_LOCAL 0 | ||
| 37 | #include <linux/uwb/debug.h> | ||
| 38 | 37 | ||
| 39 | #include "uwb-internal.h" | 38 | #include "uwb-internal.h" |
| 40 | 39 | ||
| 41 | void dump_bytes(struct device *dev, const void *_buf, size_t rsize) | ||
| 42 | { | ||
| 43 | const char *buf = _buf; | ||
| 44 | char line[32]; | ||
| 45 | size_t offset = 0; | ||
| 46 | int cnt, cnt2; | ||
| 47 | for (cnt = 0; cnt < rsize; cnt += 8) { | ||
| 48 | size_t rtop = rsize - cnt < 8 ? rsize - cnt : 8; | ||
| 49 | for (offset = cnt2 = 0; cnt2 < rtop; cnt2++) { | ||
| 50 | offset += scnprintf(line + offset, sizeof(line) - offset, | ||
| 51 | "%02x ", buf[cnt + cnt2] & 0xff); | ||
| 52 | } | ||
| 53 | if (dev) | ||
| 54 | dev_info(dev, "%s\n", line); | ||
| 55 | else | ||
| 56 | printk(KERN_INFO "%s\n", line); | ||
| 57 | } | ||
| 58 | } | ||
| 59 | EXPORT_SYMBOL_GPL(dump_bytes); | ||
| 60 | |||
| 61 | /* | 40 | /* |
| 62 | * Debug interface | 41 | * Debug interface |
| 63 | * | 42 | * |
| @@ -84,26 +63,23 @@ struct uwb_dbg { | |||
| 84 | struct dentry *reservations_f; | 63 | struct dentry *reservations_f; |
| 85 | struct dentry *accept_f; | 64 | struct dentry *accept_f; |
| 86 | struct dentry *drp_avail_f; | 65 | struct dentry *drp_avail_f; |
| 66 | spinlock_t list_lock; | ||
| 87 | }; | 67 | }; |
| 88 | 68 | ||
| 89 | static struct dentry *root_dir; | 69 | static struct dentry *root_dir; |
| 90 | 70 | ||
| 91 | static void uwb_dbg_rsv_cb(struct uwb_rsv *rsv) | 71 | static void uwb_dbg_rsv_cb(struct uwb_rsv *rsv) |
| 92 | { | 72 | { |
| 93 | struct uwb_rc *rc = rsv->rc; | 73 | struct uwb_dbg *dbg = rsv->pal_priv; |
| 94 | struct device *dev = &rc->uwb_dev.dev; | ||
| 95 | struct uwb_dev_addr devaddr; | ||
| 96 | char owner[UWB_ADDR_STRSIZE], target[UWB_ADDR_STRSIZE]; | ||
| 97 | |||
| 98 | uwb_dev_addr_print(owner, sizeof(owner), &rsv->owner->dev_addr); | ||
| 99 | if (rsv->target.type == UWB_RSV_TARGET_DEV) | ||
| 100 | devaddr = rsv->target.dev->dev_addr; | ||
| 101 | else | ||
| 102 | devaddr = rsv->target.devaddr; | ||
| 103 | uwb_dev_addr_print(target, sizeof(target), &devaddr); | ||
| 104 | 74 | ||
| 105 | dev_dbg(dev, "debug: rsv %s -> %s: %s\n", | 75 | uwb_rsv_dump("debug", rsv); |
| 106 | owner, target, uwb_rsv_state_str(rsv->state)); | 76 | |
| 77 | if (rsv->state == UWB_RSV_STATE_NONE) { | ||
| 78 | spin_lock(&dbg->list_lock); | ||
| 79 | list_del(&rsv->pal_node); | ||
| 80 | spin_unlock(&dbg->list_lock); | ||
| 81 | uwb_rsv_destroy(rsv); | ||
| 82 | } | ||
| 107 | } | 83 | } |
| 108 | 84 | ||
| 109 | static int cmd_rsv_establish(struct uwb_rc *rc, | 85 | static int cmd_rsv_establish(struct uwb_rc *rc, |
| @@ -119,26 +95,27 @@ static int cmd_rsv_establish(struct uwb_rc *rc, | |||
| 119 | if (target == NULL) | 95 | if (target == NULL) |
| 120 | return -ENODEV; | 96 | return -ENODEV; |
| 121 | 97 | ||
| 122 | rsv = uwb_rsv_create(rc, uwb_dbg_rsv_cb, NULL); | 98 | rsv = uwb_rsv_create(rc, uwb_dbg_rsv_cb, rc->dbg); |
| 123 | if (rsv == NULL) { | 99 | if (rsv == NULL) { |
| 124 | uwb_dev_put(target); | 100 | uwb_dev_put(target); |
| 125 | return -ENOMEM; | 101 | return -ENOMEM; |
| 126 | } | 102 | } |
| 127 | 103 | ||
| 128 | rsv->owner = &rc->uwb_dev; | 104 | rsv->target.type = UWB_RSV_TARGET_DEV; |
| 129 | rsv->target.type = UWB_RSV_TARGET_DEV; | 105 | rsv->target.dev = target; |
| 130 | rsv->target.dev = target; | 106 | rsv->type = cmd->type; |
| 131 | rsv->type = cmd->type; | 107 | rsv->max_mas = cmd->max_mas; |
| 132 | rsv->max_mas = cmd->max_mas; | 108 | rsv->min_mas = cmd->min_mas; |
| 133 | rsv->min_mas = cmd->min_mas; | 109 | rsv->max_interval = cmd->max_interval; |
| 134 | rsv->sparsity = cmd->sparsity; | ||
| 135 | 110 | ||
| 136 | ret = uwb_rsv_establish(rsv); | 111 | ret = uwb_rsv_establish(rsv); |
| 137 | if (ret) | 112 | if (ret) |
| 138 | uwb_rsv_destroy(rsv); | 113 | uwb_rsv_destroy(rsv); |
| 139 | else | 114 | else { |
| 115 | spin_lock(&(rc->dbg)->list_lock); | ||
| 140 | list_add_tail(&rsv->pal_node, &rc->dbg->rsvs); | 116 | list_add_tail(&rsv->pal_node, &rc->dbg->rsvs); |
| 141 | 117 | spin_unlock(&(rc->dbg)->list_lock); | |
| 118 | } | ||
| 142 | return ret; | 119 | return ret; |
| 143 | } | 120 | } |
| 144 | 121 | ||
| @@ -148,21 +125,40 @@ static int cmd_rsv_terminate(struct uwb_rc *rc, | |||
| 148 | struct uwb_rsv *rsv, *found = NULL; | 125 | struct uwb_rsv *rsv, *found = NULL; |
| 149 | int i = 0; | 126 | int i = 0; |
| 150 | 127 | ||
| 128 | spin_lock(&(rc->dbg)->list_lock); | ||
| 129 | |||
| 151 | list_for_each_entry(rsv, &rc->dbg->rsvs, pal_node) { | 130 | list_for_each_entry(rsv, &rc->dbg->rsvs, pal_node) { |
| 152 | if (i == cmd->index) { | 131 | if (i == cmd->index) { |
| 153 | found = rsv; | 132 | found = rsv; |
| 133 | uwb_rsv_get(found); | ||
| 154 | break; | 134 | break; |
| 155 | } | 135 | } |
| 136 | i++; | ||
| 156 | } | 137 | } |
| 138 | |||
| 139 | spin_unlock(&(rc->dbg)->list_lock); | ||
| 140 | |||
| 157 | if (!found) | 141 | if (!found) |
| 158 | return -EINVAL; | 142 | return -EINVAL; |
| 159 | 143 | ||
| 160 | list_del(&found->pal_node); | ||
| 161 | uwb_rsv_terminate(found); | 144 | uwb_rsv_terminate(found); |
| 145 | uwb_rsv_put(found); | ||
| 162 | 146 | ||
| 163 | return 0; | 147 | return 0; |
| 164 | } | 148 | } |
| 165 | 149 | ||
| 150 | static int cmd_ie_add(struct uwb_rc *rc, struct uwb_dbg_cmd_ie *ie_to_add) | ||
| 151 | { | ||
| 152 | return uwb_rc_ie_add(rc, | ||
| 153 | (const struct uwb_ie_hdr *) ie_to_add->data, | ||
| 154 | ie_to_add->len); | ||
| 155 | } | ||
| 156 | |||
| 157 | static int cmd_ie_rm(struct uwb_rc *rc, struct uwb_dbg_cmd_ie *ie_to_rm) | ||
| 158 | { | ||
| 159 | return uwb_rc_ie_rm(rc, ie_to_rm->data[0]); | ||
| 160 | } | ||
| 161 | |||
| 166 | static int command_open(struct inode *inode, struct file *file) | 162 | static int command_open(struct inode *inode, struct file *file) |
| 167 | { | 163 | { |
| 168 | file->private_data = inode->i_private; | 164 | file->private_data = inode->i_private; |
| @@ -175,8 +171,8 @@ static ssize_t command_write(struct file *file, const char __user *buf, | |||
| 175 | { | 171 | { |
| 176 | struct uwb_rc *rc = file->private_data; | 172 | struct uwb_rc *rc = file->private_data; |
| 177 | struct uwb_dbg_cmd cmd; | 173 | struct uwb_dbg_cmd cmd; |
| 178 | int ret; | 174 | int ret = 0; |
| 179 | 175 | ||
| 180 | if (len != sizeof(struct uwb_dbg_cmd)) | 176 | if (len != sizeof(struct uwb_dbg_cmd)) |
| 181 | return -EINVAL; | 177 | return -EINVAL; |
| 182 | 178 | ||
| @@ -190,6 +186,18 @@ static ssize_t command_write(struct file *file, const char __user *buf, | |||
| 190 | case UWB_DBG_CMD_RSV_TERMINATE: | 186 | case UWB_DBG_CMD_RSV_TERMINATE: |
| 191 | ret = cmd_rsv_terminate(rc, &cmd.rsv_terminate); | 187 | ret = cmd_rsv_terminate(rc, &cmd.rsv_terminate); |
| 192 | break; | 188 | break; |
| 189 | case UWB_DBG_CMD_IE_ADD: | ||
| 190 | ret = cmd_ie_add(rc, &cmd.ie_add); | ||
| 191 | break; | ||
| 192 | case UWB_DBG_CMD_IE_RM: | ||
| 193 | ret = cmd_ie_rm(rc, &cmd.ie_rm); | ||
| 194 | break; | ||
| 195 | case UWB_DBG_CMD_RADIO_START: | ||
| 196 | ret = uwb_radio_start(&rc->dbg->pal); | ||
| 197 | break; | ||
| 198 | case UWB_DBG_CMD_RADIO_STOP: | ||
| 199 | uwb_radio_stop(&rc->dbg->pal); | ||
| 200 | break; | ||
| 193 | default: | 201 | default: |
| 194 | return -EINVAL; | 202 | return -EINVAL; |
| 195 | } | 203 | } |
| @@ -283,12 +291,26 @@ static struct file_operations drp_avail_fops = { | |||
| 283 | .owner = THIS_MODULE, | 291 | .owner = THIS_MODULE, |
| 284 | }; | 292 | }; |
| 285 | 293 | ||
| 286 | static void uwb_dbg_new_rsv(struct uwb_rsv *rsv) | 294 | static void uwb_dbg_channel_changed(struct uwb_pal *pal, int channel) |
| 295 | { | ||
| 296 | struct device *dev = &pal->rc->uwb_dev.dev; | ||
| 297 | |||
| 298 | if (channel > 0) | ||
| 299 | dev_info(dev, "debug: channel %d started\n", channel); | ||
| 300 | else | ||
| 301 | dev_info(dev, "debug: channel stopped\n"); | ||
| 302 | } | ||
| 303 | |||
| 304 | static void uwb_dbg_new_rsv(struct uwb_pal *pal, struct uwb_rsv *rsv) | ||
| 287 | { | 305 | { |
| 288 | struct uwb_rc *rc = rsv->rc; | 306 | struct uwb_dbg *dbg = container_of(pal, struct uwb_dbg, pal); |
| 289 | 307 | ||
| 290 | if (rc->dbg->accept) | 308 | if (dbg->accept) { |
| 291 | uwb_rsv_accept(rsv, uwb_dbg_rsv_cb, NULL); | 309 | spin_lock(&dbg->list_lock); |
| 310 | list_add_tail(&rsv->pal_node, &dbg->rsvs); | ||
| 311 | spin_unlock(&dbg->list_lock); | ||
| 312 | uwb_rsv_accept(rsv, uwb_dbg_rsv_cb, dbg); | ||
| 313 | } | ||
| 292 | } | 314 | } |
| 293 | 315 | ||
| 294 | /** | 316 | /** |
| @@ -302,10 +324,14 @@ void uwb_dbg_add_rc(struct uwb_rc *rc) | |||
| 302 | return; | 324 | return; |
| 303 | 325 | ||
| 304 | INIT_LIST_HEAD(&rc->dbg->rsvs); | 326 | INIT_LIST_HEAD(&rc->dbg->rsvs); |
| 327 | spin_lock_init(&(rc->dbg)->list_lock); | ||
| 305 | 328 | ||
| 306 | uwb_pal_init(&rc->dbg->pal); | 329 | uwb_pal_init(&rc->dbg->pal); |
| 330 | rc->dbg->pal.rc = rc; | ||
| 331 | rc->dbg->pal.channel_changed = uwb_dbg_channel_changed; | ||
| 307 | rc->dbg->pal.new_rsv = uwb_dbg_new_rsv; | 332 | rc->dbg->pal.new_rsv = uwb_dbg_new_rsv; |
| 308 | uwb_pal_register(rc, &rc->dbg->pal); | 333 | uwb_pal_register(&rc->dbg->pal); |
| 334 | |||
| 309 | if (root_dir) { | 335 | if (root_dir) { |
| 310 | rc->dbg->root_d = debugfs_create_dir(dev_name(&rc->uwb_dev.dev), | 336 | rc->dbg->root_d = debugfs_create_dir(dev_name(&rc->uwb_dev.dev), |
| 311 | root_dir); | 337 | root_dir); |
| @@ -325,7 +351,7 @@ void uwb_dbg_add_rc(struct uwb_rc *rc) | |||
| 325 | } | 351 | } |
| 326 | 352 | ||
| 327 | /** | 353 | /** |
| 328 | * uwb_dbg_add_rc - remove a radio controller's debug interface | 354 | * uwb_dbg_del_rc - remove a radio controller's debug interface |
| 329 | * @rc: the radio controller | 355 | * @rc: the radio controller |
| 330 | */ | 356 | */ |
| 331 | void uwb_dbg_del_rc(struct uwb_rc *rc) | 357 | void uwb_dbg_del_rc(struct uwb_rc *rc) |
| @@ -336,10 +362,10 @@ void uwb_dbg_del_rc(struct uwb_rc *rc) | |||
| 336 | return; | 362 | return; |
| 337 | 363 | ||
| 338 | list_for_each_entry_safe(rsv, t, &rc->dbg->rsvs, pal_node) { | 364 | list_for_each_entry_safe(rsv, t, &rc->dbg->rsvs, pal_node) { |
| 339 | uwb_rsv_destroy(rsv); | 365 | uwb_rsv_terminate(rsv); |
| 340 | } | 366 | } |
| 341 | 367 | ||
| 342 | uwb_pal_unregister(rc, &rc->dbg->pal); | 368 | uwb_pal_unregister(&rc->dbg->pal); |
| 343 | 369 | ||
| 344 | if (root_dir) { | 370 | if (root_dir) { |
| 345 | debugfs_remove(rc->dbg->drp_avail_f); | 371 | debugfs_remove(rc->dbg->drp_avail_f); |
| @@ -365,3 +391,16 @@ void uwb_dbg_exit(void) | |||
| 365 | { | 391 | { |
| 366 | debugfs_remove(root_dir); | 392 | debugfs_remove(root_dir); |
| 367 | } | 393 | } |
| 394 | |||
| 395 | /** | ||
| 396 | * uwb_dbg_create_pal_dir - create a debugfs directory for a PAL | ||
| 397 | * @pal: The PAL. | ||
| 398 | */ | ||
| 399 | struct dentry *uwb_dbg_create_pal_dir(struct uwb_pal *pal) | ||
| 400 | { | ||
| 401 | struct uwb_rc *rc = pal->rc; | ||
| 402 | |||
| 403 | if (root_dir && rc->dbg && rc->dbg->root_d && pal->name) | ||
| 404 | return debugfs_create_dir(pal->name, rc->dbg->root_d); | ||
| 405 | return NULL; | ||
| 406 | } | ||
diff --git a/drivers/uwb/uwb-internal.h b/drivers/uwb/uwb-internal.h index 2ad307d1296..d5bcfc1c227 100644 --- a/drivers/uwb/uwb-internal.h +++ b/drivers/uwb/uwb-internal.h | |||
| @@ -66,14 +66,14 @@ extern int uwb_rc_scan(struct uwb_rc *rc, | |||
| 66 | unsigned channel, enum uwb_scan_type type, | 66 | unsigned channel, enum uwb_scan_type type, |
| 67 | unsigned bpst_offset); | 67 | unsigned bpst_offset); |
| 68 | extern int uwb_rc_send_all_drp_ie(struct uwb_rc *rc); | 68 | extern int uwb_rc_send_all_drp_ie(struct uwb_rc *rc); |
| 69 | extern ssize_t uwb_rc_print_IEs(struct uwb_rc *rc, char *, size_t); | 69 | |
| 70 | extern void uwb_rc_ie_init(struct uwb_rc *); | 70 | void uwb_rc_ie_init(struct uwb_rc *); |
| 71 | extern void uwb_rc_ie_init(struct uwb_rc *); | 71 | int uwb_rc_ie_setup(struct uwb_rc *); |
| 72 | extern ssize_t uwb_rc_ie_setup(struct uwb_rc *); | 72 | void uwb_rc_ie_release(struct uwb_rc *); |
| 73 | extern void uwb_rc_ie_release(struct uwb_rc *); | 73 | int uwb_ie_dump_hex(const struct uwb_ie_hdr *ies, size_t len, |
| 74 | extern int uwb_rc_ie_add(struct uwb_rc *, | 74 | char *buf, size_t size); |
| 75 | const struct uwb_ie_hdr *, size_t); | 75 | int uwb_rc_set_ie(struct uwb_rc *, struct uwb_rc_cmd_set_ie *); |
| 76 | extern int uwb_rc_ie_rm(struct uwb_rc *, enum uwb_ie); | 76 | |
| 77 | 77 | ||
| 78 | extern const char *uwb_rc_strerror(unsigned code); | 78 | extern const char *uwb_rc_strerror(unsigned code); |
| 79 | 79 | ||
| @@ -92,6 +92,12 @@ extern const char *uwb_rc_strerror(unsigned code); | |||
| 92 | 92 | ||
| 93 | struct uwb_rc_neh; | 93 | struct uwb_rc_neh; |
| 94 | 94 | ||
| 95 | extern int uwb_rc_cmd_async(struct uwb_rc *rc, const char *cmd_name, | ||
| 96 | struct uwb_rccb *cmd, size_t cmd_size, | ||
| 97 | u8 expected_type, u16 expected_event, | ||
| 98 | uwb_rc_cmd_cb_f cb, void *arg); | ||
| 99 | |||
| 100 | |||
| 95 | void uwb_rc_neh_create(struct uwb_rc *rc); | 101 | void uwb_rc_neh_create(struct uwb_rc *rc); |
| 96 | void uwb_rc_neh_destroy(struct uwb_rc *rc); | 102 | void uwb_rc_neh_destroy(struct uwb_rc *rc); |
| 97 | 103 | ||
| @@ -106,7 +112,69 @@ void uwb_rc_neh_put(struct uwb_rc_neh *neh); | |||
| 106 | extern int uwb_est_create(void); | 112 | extern int uwb_est_create(void); |
| 107 | extern void uwb_est_destroy(void); | 113 | extern void uwb_est_destroy(void); |
| 108 | 114 | ||
| 115 | /* | ||
| 116 | * UWB conflicting alien reservations | ||
| 117 | */ | ||
| 118 | struct uwb_cnflt_alien { | ||
| 119 | struct uwb_rc *rc; | ||
| 120 | struct list_head rc_node; | ||
| 121 | struct uwb_mas_bm mas; | ||
| 122 | struct timer_list timer; | ||
| 123 | struct work_struct cnflt_update_work; | ||
| 124 | }; | ||
| 125 | |||
| 126 | enum uwb_uwb_rsv_alloc_result { | ||
| 127 | UWB_RSV_ALLOC_FOUND = 0, | ||
| 128 | UWB_RSV_ALLOC_NOT_FOUND, | ||
| 129 | }; | ||
| 130 | |||
| 131 | enum uwb_rsv_mas_status { | ||
| 132 | UWB_RSV_MAS_NOT_AVAIL = 1, | ||
| 133 | UWB_RSV_MAS_SAFE, | ||
| 134 | UWB_RSV_MAS_UNSAFE, | ||
| 135 | }; | ||
| 136 | |||
| 137 | struct uwb_rsv_col_set_info { | ||
| 138 | unsigned char start_col; | ||
| 139 | unsigned char interval; | ||
| 140 | unsigned char safe_mas_per_col; | ||
| 141 | unsigned char unsafe_mas_per_col; | ||
| 142 | }; | ||
| 143 | |||
| 144 | struct uwb_rsv_col_info { | ||
| 145 | unsigned char max_avail_safe; | ||
| 146 | unsigned char max_avail_unsafe; | ||
| 147 | unsigned char highest_mas[UWB_MAS_PER_ZONE]; | ||
| 148 | struct uwb_rsv_col_set_info csi; | ||
| 149 | }; | ||
| 150 | |||
| 151 | struct uwb_rsv_row_info { | ||
| 152 | unsigned char avail[UWB_MAS_PER_ZONE]; | ||
| 153 | unsigned char free_rows; | ||
| 154 | unsigned char used_rows; | ||
| 155 | }; | ||
| 156 | |||
| 157 | /* | ||
| 158 | * UWB find allocation | ||
| 159 | */ | ||
| 160 | struct uwb_rsv_alloc_info { | ||
| 161 | unsigned char bm[UWB_MAS_PER_ZONE * UWB_NUM_ZONES]; | ||
| 162 | struct uwb_rsv_col_info ci[UWB_NUM_ZONES]; | ||
| 163 | struct uwb_rsv_row_info ri; | ||
| 164 | struct uwb_mas_bm *not_available; | ||
| 165 | struct uwb_mas_bm *result; | ||
| 166 | int min_mas; | ||
| 167 | int max_mas; | ||
| 168 | int max_interval; | ||
| 169 | int total_allocated_mases; | ||
| 170 | int safe_allocated_mases; | ||
| 171 | int unsafe_allocated_mases; | ||
| 172 | int interval; | ||
| 173 | }; | ||
| 109 | 174 | ||
| 175 | int uwb_rsv_find_best_allocation(struct uwb_rsv *rsv, struct uwb_mas_bm *available, | ||
| 176 | struct uwb_mas_bm *result); | ||
| 177 | void uwb_rsv_handle_drp_avail_change(struct uwb_rc *rc); | ||
| 110 | /* | 178 | /* |
| 111 | * UWB Events & management daemon | 179 | * UWB Events & management daemon |
| 112 | */ | 180 | */ |
| @@ -160,13 +228,14 @@ struct uwb_event { | |||
| 160 | }; | 228 | }; |
| 161 | }; | 229 | }; |
| 162 | 230 | ||
| 163 | extern void uwbd_start(void); | 231 | extern void uwbd_start(struct uwb_rc *rc); |
| 164 | extern void uwbd_stop(void); | 232 | extern void uwbd_stop(struct uwb_rc *rc); |
| 165 | extern struct uwb_event *uwb_event_alloc(size_t, gfp_t gfp_mask); | 233 | extern struct uwb_event *uwb_event_alloc(size_t, gfp_t gfp_mask); |
| 166 | extern void uwbd_event_queue(struct uwb_event *); | 234 | extern void uwbd_event_queue(struct uwb_event *); |
| 167 | void uwbd_flush(struct uwb_rc *rc); | 235 | void uwbd_flush(struct uwb_rc *rc); |
| 168 | 236 | ||
| 169 | /* UWB event handlers */ | 237 | /* UWB event handlers */ |
| 238 | extern int uwbd_evt_handle_rc_ie_rcv(struct uwb_event *); | ||
| 170 | extern int uwbd_evt_handle_rc_beacon(struct uwb_event *); | 239 | extern int uwbd_evt_handle_rc_beacon(struct uwb_event *); |
| 171 | extern int uwbd_evt_handle_rc_beacon_size(struct uwb_event *); | 240 | extern int uwbd_evt_handle_rc_beacon_size(struct uwb_event *); |
| 172 | extern int uwbd_evt_handle_rc_bpoie_change(struct uwb_event *); | 241 | extern int uwbd_evt_handle_rc_bpoie_change(struct uwb_event *); |
| @@ -193,15 +262,6 @@ int uwbd_evt_handle_rc_dev_addr_conflict(struct uwb_event *evt); | |||
| 193 | 262 | ||
| 194 | extern unsigned long beacon_timeout_ms; | 263 | extern unsigned long beacon_timeout_ms; |
| 195 | 264 | ||
| 196 | /** Beacon cache list */ | ||
| 197 | struct uwb_beca { | ||
| 198 | struct list_head list; | ||
| 199 | size_t entries; | ||
| 200 | struct mutex mutex; | ||
| 201 | }; | ||
| 202 | |||
| 203 | extern struct uwb_beca uwb_beca; | ||
| 204 | |||
| 205 | /** | 265 | /** |
| 206 | * Beacon cache entry | 266 | * Beacon cache entry |
| 207 | * | 267 | * |
| @@ -228,9 +288,6 @@ struct uwb_beca_e { | |||
| 228 | struct uwb_beacon_frame; | 288 | struct uwb_beacon_frame; |
| 229 | extern ssize_t uwb_bce_print_IEs(struct uwb_dev *, struct uwb_beca_e *, | 289 | extern ssize_t uwb_bce_print_IEs(struct uwb_dev *, struct uwb_beca_e *, |
| 230 | char *, size_t); | 290 | char *, size_t); |
| 231 | extern struct uwb_beca_e *__uwb_beca_add(struct uwb_rc_evt_beacon *, | ||
| 232 | struct uwb_beacon_frame *, | ||
| 233 | unsigned long); | ||
| 234 | 291 | ||
| 235 | extern void uwb_bce_kfree(struct kref *_bce); | 292 | extern void uwb_bce_kfree(struct kref *_bce); |
| 236 | static inline void uwb_bce_get(struct uwb_beca_e *bce) | 293 | static inline void uwb_bce_get(struct uwb_beca_e *bce) |
| @@ -241,14 +298,19 @@ static inline void uwb_bce_put(struct uwb_beca_e *bce) | |||
| 241 | { | 298 | { |
| 242 | kref_put(&bce->refcnt, uwb_bce_kfree); | 299 | kref_put(&bce->refcnt, uwb_bce_kfree); |
| 243 | } | 300 | } |
| 244 | extern void uwb_beca_purge(void); | 301 | extern void uwb_beca_purge(struct uwb_rc *rc); |
| 245 | extern void uwb_beca_release(void); | 302 | extern void uwb_beca_release(struct uwb_rc *rc); |
| 246 | 303 | ||
| 247 | struct uwb_dev *uwb_dev_get_by_devaddr(struct uwb_rc *rc, | 304 | struct uwb_dev *uwb_dev_get_by_devaddr(struct uwb_rc *rc, |
| 248 | const struct uwb_dev_addr *devaddr); | 305 | const struct uwb_dev_addr *devaddr); |
| 249 | struct uwb_dev *uwb_dev_get_by_macaddr(struct uwb_rc *rc, | 306 | struct uwb_dev *uwb_dev_get_by_macaddr(struct uwb_rc *rc, |
| 250 | const struct uwb_mac_addr *macaddr); | 307 | const struct uwb_mac_addr *macaddr); |
| 251 | 308 | ||
| 309 | int uwb_radio_setup(struct uwb_rc *rc); | ||
| 310 | void uwb_radio_reset_state(struct uwb_rc *rc); | ||
| 311 | void uwb_radio_shutdown(struct uwb_rc *rc); | ||
| 312 | int uwb_radio_force_channel(struct uwb_rc *rc, int channel); | ||
| 313 | |||
| 252 | /* -- UWB Sysfs representation */ | 314 | /* -- UWB Sysfs representation */ |
| 253 | extern struct class uwb_rc_class; | 315 | extern struct class uwb_rc_class; |
| 254 | extern struct device_attribute dev_attr_mac_address; | 316 | extern struct device_attribute dev_attr_mac_address; |
| @@ -259,18 +321,29 @@ extern struct device_attribute dev_attr_scan; | |||
| 259 | void uwb_rsv_init(struct uwb_rc *rc); | 321 | void uwb_rsv_init(struct uwb_rc *rc); |
| 260 | int uwb_rsv_setup(struct uwb_rc *rc); | 322 | int uwb_rsv_setup(struct uwb_rc *rc); |
| 261 | void uwb_rsv_cleanup(struct uwb_rc *rc); | 323 | void uwb_rsv_cleanup(struct uwb_rc *rc); |
| 324 | void uwb_rsv_remove_all(struct uwb_rc *rc); | ||
| 325 | void uwb_rsv_get(struct uwb_rsv *rsv); | ||
| 326 | void uwb_rsv_put(struct uwb_rsv *rsv); | ||
| 327 | bool uwb_rsv_has_two_drp_ies(struct uwb_rsv *rsv); | ||
| 328 | void uwb_rsv_dump(char *text, struct uwb_rsv *rsv); | ||
| 329 | int uwb_rsv_try_move(struct uwb_rsv *rsv, struct uwb_mas_bm *available); | ||
| 330 | void uwb_rsv_backoff_win_timer(unsigned long arg); | ||
| 331 | void uwb_rsv_backoff_win_increment(struct uwb_rc *rc); | ||
| 332 | int uwb_rsv_status(struct uwb_rsv *rsv); | ||
| 333 | int uwb_rsv_companion_status(struct uwb_rsv *rsv); | ||
| 262 | 334 | ||
| 263 | void uwb_rsv_set_state(struct uwb_rsv *rsv, enum uwb_rsv_state new_state); | 335 | void uwb_rsv_set_state(struct uwb_rsv *rsv, enum uwb_rsv_state new_state); |
| 264 | void uwb_rsv_remove(struct uwb_rsv *rsv); | 336 | void uwb_rsv_remove(struct uwb_rsv *rsv); |
| 265 | struct uwb_rsv *uwb_rsv_find(struct uwb_rc *rc, struct uwb_dev *src, | 337 | struct uwb_rsv *uwb_rsv_find(struct uwb_rc *rc, struct uwb_dev *src, |
| 266 | struct uwb_ie_drp *drp_ie); | 338 | struct uwb_ie_drp *drp_ie); |
| 267 | void uwb_rsv_sched_update(struct uwb_rc *rc); | 339 | void uwb_rsv_sched_update(struct uwb_rc *rc); |
| 340 | void uwb_rsv_queue_update(struct uwb_rc *rc); | ||
| 268 | 341 | ||
| 269 | void uwb_drp_handle_timeout(struct uwb_rsv *rsv); | ||
| 270 | int uwb_drp_ie_update(struct uwb_rsv *rsv); | 342 | int uwb_drp_ie_update(struct uwb_rsv *rsv); |
| 271 | void uwb_drp_ie_to_bm(struct uwb_mas_bm *bm, const struct uwb_ie_drp *drp_ie); | 343 | void uwb_drp_ie_to_bm(struct uwb_mas_bm *bm, const struct uwb_ie_drp *drp_ie); |
| 272 | 344 | ||
| 273 | void uwb_drp_avail_init(struct uwb_rc *rc); | 345 | void uwb_drp_avail_init(struct uwb_rc *rc); |
| 346 | void uwb_drp_available(struct uwb_rc *rc, struct uwb_mas_bm *avail); | ||
| 274 | int uwb_drp_avail_reserve_pending(struct uwb_rc *rc, struct uwb_mas_bm *mas); | 347 | int uwb_drp_avail_reserve_pending(struct uwb_rc *rc, struct uwb_mas_bm *mas); |
| 275 | void uwb_drp_avail_reserve(struct uwb_rc *rc, struct uwb_mas_bm *mas); | 348 | void uwb_drp_avail_reserve(struct uwb_rc *rc, struct uwb_mas_bm *mas); |
| 276 | void uwb_drp_avail_release(struct uwb_rc *rc, struct uwb_mas_bm *mas); | 349 | void uwb_drp_avail_release(struct uwb_rc *rc, struct uwb_mas_bm *mas); |
| @@ -289,8 +362,7 @@ void uwb_dbg_init(void); | |||
| 289 | void uwb_dbg_exit(void); | 362 | void uwb_dbg_exit(void); |
| 290 | void uwb_dbg_add_rc(struct uwb_rc *rc); | 363 | void uwb_dbg_add_rc(struct uwb_rc *rc); |
| 291 | void uwb_dbg_del_rc(struct uwb_rc *rc); | 364 | void uwb_dbg_del_rc(struct uwb_rc *rc); |
| 292 | 365 | struct dentry *uwb_dbg_create_pal_dir(struct uwb_pal *pal); | |
| 293 | /* Workarounds for version specific stuff */ | ||
| 294 | 366 | ||
| 295 | static inline void uwb_dev_lock(struct uwb_dev *uwb_dev) | 367 | static inline void uwb_dev_lock(struct uwb_dev *uwb_dev) |
| 296 | { | 368 | { |
diff --git a/drivers/uwb/uwbd.c b/drivers/uwb/uwbd.c index 78908416e42..57bd6bfef37 100644 --- a/drivers/uwb/uwbd.c +++ b/drivers/uwb/uwbd.c | |||
| @@ -68,17 +68,13 @@ | |||
| 68 | * | 68 | * |
| 69 | * Handler functions are called normally uwbd_evt_handle_*(). | 69 | * Handler functions are called normally uwbd_evt_handle_*(). |
| 70 | */ | 70 | */ |
| 71 | |||
| 72 | #include <linux/kthread.h> | 71 | #include <linux/kthread.h> |
| 73 | #include <linux/module.h> | 72 | #include <linux/module.h> |
| 74 | #include <linux/freezer.h> | 73 | #include <linux/freezer.h> |
| 75 | #include "uwb-internal.h" | ||
| 76 | |||
| 77 | #define D_LOCAL 1 | ||
| 78 | #include <linux/uwb/debug.h> | ||
| 79 | 74 | ||
| 75 | #include "uwb-internal.h" | ||
| 80 | 76 | ||
| 81 | /** | 77 | /* |
| 82 | * UWBD Event handler function signature | 78 | * UWBD Event handler function signature |
| 83 | * | 79 | * |
| 84 | * Return !0 if the event needs not to be freed (ie the handler | 80 | * Return !0 if the event needs not to be freed (ie the handler |
| @@ -101,9 +97,12 @@ struct uwbd_event { | |||
| 101 | const char *name; | 97 | const char *name; |
| 102 | }; | 98 | }; |
| 103 | 99 | ||
| 104 | /** Table of handlers for and properties of the UWBD Radio Control Events */ | 100 | /* Table of handlers for and properties of the UWBD Radio Control Events */ |
| 105 | static | 101 | static struct uwbd_event uwbd_urc_events[] = { |
| 106 | struct uwbd_event uwbd_events[] = { | 102 | [UWB_RC_EVT_IE_RCV] = { |
| 103 | .handler = uwbd_evt_handle_rc_ie_rcv, | ||
| 104 | .name = "IE_RECEIVED" | ||
| 105 | }, | ||
| 107 | [UWB_RC_EVT_BEACON] = { | 106 | [UWB_RC_EVT_BEACON] = { |
| 108 | .handler = uwbd_evt_handle_rc_beacon, | 107 | .handler = uwbd_evt_handle_rc_beacon, |
| 109 | .name = "BEACON_RECEIVED" | 108 | .name = "BEACON_RECEIVED" |
| @@ -142,23 +141,15 @@ struct uwbd_evt_type_handler { | |||
| 142 | size_t size; | 141 | size_t size; |
| 143 | }; | 142 | }; |
| 144 | 143 | ||
| 145 | #define UWBD_EVT_TYPE_HANDLER(n,a) { \ | 144 | /* Table of handlers for each UWBD Event type. */ |
| 146 | .name = (n), \ | 145 | static struct uwbd_evt_type_handler uwbd_urc_evt_type_handlers[] = { |
| 147 | .uwbd_events = (a), \ | 146 | [UWB_RC_CET_GENERAL] = { |
| 148 | .size = sizeof(a)/sizeof((a)[0]) \ | 147 | .name = "URC", |
| 149 | } | 148 | .uwbd_events = uwbd_urc_events, |
| 150 | 149 | .size = ARRAY_SIZE(uwbd_urc_events), | |
| 151 | 150 | }, | |
| 152 | /** Table of handlers for each UWBD Event type. */ | ||
| 153 | static | ||
| 154 | struct uwbd_evt_type_handler uwbd_evt_type_handlers[] = { | ||
| 155 | [UWB_RC_CET_GENERAL] = UWBD_EVT_TYPE_HANDLER("RC", uwbd_events) | ||
| 156 | }; | 151 | }; |
| 157 | 152 | ||
| 158 | static const | ||
| 159 | size_t uwbd_evt_type_handlers_len = | ||
| 160 | sizeof(uwbd_evt_type_handlers) / sizeof(uwbd_evt_type_handlers[0]); | ||
| 161 | |||
| 162 | static const struct uwbd_event uwbd_message_handlers[] = { | 153 | static const struct uwbd_event uwbd_message_handlers[] = { |
| 163 | [UWB_EVT_MSG_RESET] = { | 154 | [UWB_EVT_MSG_RESET] = { |
| 164 | .handler = uwbd_msg_handle_reset, | 155 | .handler = uwbd_msg_handle_reset, |
| @@ -166,9 +157,7 @@ static const struct uwbd_event uwbd_message_handlers[] = { | |||
| 166 | }, | 157 | }, |
| 167 | }; | 158 | }; |
| 168 | 159 | ||
| 169 | static DEFINE_MUTEX(uwbd_event_mutex); | 160 | /* |
| 170 | |||
| 171 | /** | ||
| 172 | * Handle an URC event passed to the UWB Daemon | 161 | * Handle an URC event passed to the UWB Daemon |
| 173 | * | 162 | * |
| 174 | * @evt: the event to handle | 163 | * @evt: the event to handle |
| @@ -188,6 +177,7 @@ static DEFINE_MUTEX(uwbd_event_mutex); | |||
| 188 | static | 177 | static |
| 189 | int uwbd_event_handle_urc(struct uwb_event *evt) | 178 | int uwbd_event_handle_urc(struct uwb_event *evt) |
| 190 | { | 179 | { |
| 180 | int result = -EINVAL; | ||
| 191 | struct uwbd_evt_type_handler *type_table; | 181 | struct uwbd_evt_type_handler *type_table; |
| 192 | uwbd_evt_handler_f handler; | 182 | uwbd_evt_handler_f handler; |
| 193 | u8 type, context; | 183 | u8 type, context; |
| @@ -197,26 +187,24 @@ int uwbd_event_handle_urc(struct uwb_event *evt) | |||
| 197 | event = le16_to_cpu(evt->notif.rceb->wEvent); | 187 | event = le16_to_cpu(evt->notif.rceb->wEvent); |
| 198 | context = evt->notif.rceb->bEventContext; | 188 | context = evt->notif.rceb->bEventContext; |
| 199 | 189 | ||
| 200 | if (type > uwbd_evt_type_handlers_len) { | 190 | if (type > ARRAY_SIZE(uwbd_urc_evt_type_handlers)) |
| 201 | printk(KERN_ERR "UWBD: event type %u: unknown (too high)\n", type); | 191 | goto out; |
| 202 | return -EINVAL; | 192 | type_table = &uwbd_urc_evt_type_handlers[type]; |
| 203 | } | 193 | if (type_table->uwbd_events == NULL) |
| 204 | type_table = &uwbd_evt_type_handlers[type]; | 194 | goto out; |
| 205 | if (type_table->uwbd_events == NULL) { | 195 | if (event > type_table->size) |
| 206 | printk(KERN_ERR "UWBD: event type %u: unknown\n", type); | 196 | goto out; |
| 207 | return -EINVAL; | ||
| 208 | } | ||
| 209 | if (event > type_table->size) { | ||
| 210 | printk(KERN_ERR "UWBD: event %s[%u]: unknown (too high)\n", | ||
| 211 | type_table->name, event); | ||
| 212 | return -EINVAL; | ||
| 213 | } | ||
| 214 | handler = type_table->uwbd_events[event].handler; | 197 | handler = type_table->uwbd_events[event].handler; |
| 215 | if (handler == NULL) { | 198 | if (handler == NULL) |
| 216 | printk(KERN_ERR "UWBD: event %s[%u]: unknown\n", type_table->name, event); | 199 | goto out; |
| 217 | return -EINVAL; | 200 | |
| 218 | } | 201 | result = (*handler)(evt); |
| 219 | return (*handler)(evt); | 202 | out: |
| 203 | if (result < 0) | ||
| 204 | dev_err(&evt->rc->uwb_dev.dev, | ||
| 205 | "UWBD: event 0x%02x/%04x/%02x, handling failed: %d\n", | ||
| 206 | type, event, context, result); | ||
| 207 | return result; | ||
| 220 | } | 208 | } |
| 221 | 209 | ||
| 222 | static void uwbd_event_handle_message(struct uwb_event *evt) | 210 | static void uwbd_event_handle_message(struct uwb_event *evt) |
| @@ -231,19 +219,10 @@ static void uwbd_event_handle_message(struct uwb_event *evt) | |||
| 231 | return; | 219 | return; |
| 232 | } | 220 | } |
| 233 | 221 | ||
| 234 | /* If this is a reset event we need to drop the | ||
| 235 | * uwbd_event_mutex or it deadlocks when the reset handler | ||
| 236 | * attempts to flush the uwbd events. */ | ||
| 237 | if (evt->message == UWB_EVT_MSG_RESET) | ||
| 238 | mutex_unlock(&uwbd_event_mutex); | ||
| 239 | |||
| 240 | result = uwbd_message_handlers[evt->message].handler(evt); | 222 | result = uwbd_message_handlers[evt->message].handler(evt); |
| 241 | if (result < 0) | 223 | if (result < 0) |
| 242 | dev_err(&rc->uwb_dev.dev, "UWBD: '%s' message failed: %d\n", | 224 | dev_err(&rc->uwb_dev.dev, "UWBD: '%s' message failed: %d\n", |
| 243 | uwbd_message_handlers[evt->message].name, result); | 225 | uwbd_message_handlers[evt->message].name, result); |
| 244 | |||
| 245 | if (evt->message == UWB_EVT_MSG_RESET) | ||
| 246 | mutex_lock(&uwbd_event_mutex); | ||
| 247 | } | 226 | } |
| 248 | 227 | ||
| 249 | static void uwbd_event_handle(struct uwb_event *evt) | 228 | static void uwbd_event_handle(struct uwb_event *evt) |
| @@ -271,20 +250,6 @@ static void uwbd_event_handle(struct uwb_event *evt) | |||
| 271 | 250 | ||
| 272 | __uwb_rc_put(rc); /* for the __uwb_rc_get() in uwb_rc_notif_cb() */ | 251 | __uwb_rc_put(rc); /* for the __uwb_rc_get() in uwb_rc_notif_cb() */ |
| 273 | } | 252 | } |
| 274 | /* The UWB Daemon */ | ||
| 275 | |||
| 276 | |||
| 277 | /** Daemon's PID: used to decide if we can queue or not */ | ||
| 278 | static int uwbd_pid; | ||
| 279 | /** Daemon's task struct for managing the kthread */ | ||
| 280 | static struct task_struct *uwbd_task; | ||
| 281 | /** Daemon's waitqueue for waiting for new events */ | ||
| 282 | static DECLARE_WAIT_QUEUE_HEAD(uwbd_wq); | ||
| 283 | /** Daemon's list of events; we queue/dequeue here */ | ||
| 284 | static struct list_head uwbd_event_list = LIST_HEAD_INIT(uwbd_event_list); | ||
| 285 | /** Daemon's list lock to protect concurent access */ | ||
| 286 | static DEFINE_SPINLOCK(uwbd_event_list_lock); | ||
| 287 | |||
| 288 | 253 | ||
| 289 | /** | 254 | /** |
| 290 | * UWB Daemon | 255 | * UWB Daemon |
| @@ -298,65 +263,58 @@ static DEFINE_SPINLOCK(uwbd_event_list_lock); | |||
| 298 | * FIXME: should change so we don't have a 1HZ timer all the time, but | 263 | * FIXME: should change so we don't have a 1HZ timer all the time, but |
| 299 | * only if there are devices. | 264 | * only if there are devices. |
| 300 | */ | 265 | */ |
| 301 | static int uwbd(void *unused) | 266 | static int uwbd(void *param) |
| 302 | { | 267 | { |
| 268 | struct uwb_rc *rc = param; | ||
| 303 | unsigned long flags; | 269 | unsigned long flags; |
| 304 | struct list_head list = LIST_HEAD_INIT(list); | 270 | struct uwb_event *evt; |
| 305 | struct uwb_event *evt, *nxt; | ||
| 306 | int should_stop = 0; | 271 | int should_stop = 0; |
| 272 | |||
| 307 | while (1) { | 273 | while (1) { |
| 308 | wait_event_interruptible_timeout( | 274 | wait_event_interruptible_timeout( |
| 309 | uwbd_wq, | 275 | rc->uwbd.wq, |
| 310 | !list_empty(&uwbd_event_list) | 276 | !list_empty(&rc->uwbd.event_list) |
| 311 | || (should_stop = kthread_should_stop()), | 277 | || (should_stop = kthread_should_stop()), |
| 312 | HZ); | 278 | HZ); |
| 313 | if (should_stop) | 279 | if (should_stop) |
| 314 | break; | 280 | break; |
| 315 | try_to_freeze(); | 281 | try_to_freeze(); |
| 316 | 282 | ||
| 317 | mutex_lock(&uwbd_event_mutex); | 283 | spin_lock_irqsave(&rc->uwbd.event_list_lock, flags); |
| 318 | spin_lock_irqsave(&uwbd_event_list_lock, flags); | 284 | if (!list_empty(&rc->uwbd.event_list)) { |
| 319 | list_splice_init(&uwbd_event_list, &list); | 285 | evt = list_first_entry(&rc->uwbd.event_list, struct uwb_event, list_node); |
| 320 | spin_unlock_irqrestore(&uwbd_event_list_lock, flags); | ||
| 321 | list_for_each_entry_safe(evt, nxt, &list, list_node) { | ||
| 322 | list_del(&evt->list_node); | 286 | list_del(&evt->list_node); |
| 287 | } else | ||
| 288 | evt = NULL; | ||
| 289 | spin_unlock_irqrestore(&rc->uwbd.event_list_lock, flags); | ||
| 290 | |||
| 291 | if (evt) { | ||
| 323 | uwbd_event_handle(evt); | 292 | uwbd_event_handle(evt); |
| 324 | kfree(evt); | 293 | kfree(evt); |
| 325 | } | 294 | } |
| 326 | mutex_unlock(&uwbd_event_mutex); | ||
| 327 | 295 | ||
| 328 | uwb_beca_purge(); /* Purge devices that left */ | 296 | uwb_beca_purge(rc); /* Purge devices that left */ |
| 329 | } | 297 | } |
| 330 | return 0; | 298 | return 0; |
| 331 | } | 299 | } |
| 332 | 300 | ||
| 333 | 301 | ||
| 334 | /** Start the UWB daemon */ | 302 | /** Start the UWB daemon */ |
| 335 | void uwbd_start(void) | 303 | void uwbd_start(struct uwb_rc *rc) |
| 336 | { | 304 | { |
| 337 | uwbd_task = kthread_run(uwbd, NULL, "uwbd"); | 305 | rc->uwbd.task = kthread_run(uwbd, rc, "uwbd"); |
| 338 | if (uwbd_task == NULL) | 306 | if (rc->uwbd.task == NULL) |
| 339 | printk(KERN_ERR "UWB: Cannot start management daemon; " | 307 | printk(KERN_ERR "UWB: Cannot start management daemon; " |
| 340 | "UWB won't work\n"); | 308 | "UWB won't work\n"); |
| 341 | else | 309 | else |
| 342 | uwbd_pid = uwbd_task->pid; | 310 | rc->uwbd.pid = rc->uwbd.task->pid; |
| 343 | } | 311 | } |
| 344 | 312 | ||
| 345 | /* Stop the UWB daemon and free any unprocessed events */ | 313 | /* Stop the UWB daemon and free any unprocessed events */ |
| 346 | void uwbd_stop(void) | 314 | void uwbd_stop(struct uwb_rc *rc) |
| 347 | { | 315 | { |
| 348 | unsigned long flags; | 316 | kthread_stop(rc->uwbd.task); |
| 349 | struct uwb_event *evt, *nxt; | 317 | uwbd_flush(rc); |
| 350 | kthread_stop(uwbd_task); | ||
| 351 | spin_lock_irqsave(&uwbd_event_list_lock, flags); | ||
| 352 | uwbd_pid = 0; | ||
| 353 | list_for_each_entry_safe(evt, nxt, &uwbd_event_list, list_node) { | ||
| 354 | if (evt->type == UWB_EVT_TYPE_NOTIF) | ||
| 355 | kfree(evt->notif.rceb); | ||
| 356 | kfree(evt); | ||
| 357 | } | ||
| 358 | spin_unlock_irqrestore(&uwbd_event_list_lock, flags); | ||
| 359 | uwb_beca_release(); | ||
| 360 | } | 318 | } |
| 361 | 319 | ||
| 362 | /* | 320 | /* |
| @@ -373,18 +331,20 @@ void uwbd_stop(void) | |||
| 373 | */ | 331 | */ |
| 374 | void uwbd_event_queue(struct uwb_event *evt) | 332 | void uwbd_event_queue(struct uwb_event *evt) |
| 375 | { | 333 | { |
| 334 | struct uwb_rc *rc = evt->rc; | ||
| 376 | unsigned long flags; | 335 | unsigned long flags; |
| 377 | spin_lock_irqsave(&uwbd_event_list_lock, flags); | 336 | |
| 378 | if (uwbd_pid != 0) { | 337 | spin_lock_irqsave(&rc->uwbd.event_list_lock, flags); |
| 379 | list_add(&evt->list_node, &uwbd_event_list); | 338 | if (rc->uwbd.pid != 0) { |
| 380 | wake_up_all(&uwbd_wq); | 339 | list_add(&evt->list_node, &rc->uwbd.event_list); |
| 340 | wake_up_all(&rc->uwbd.wq); | ||
| 381 | } else { | 341 | } else { |
| 382 | __uwb_rc_put(evt->rc); | 342 | __uwb_rc_put(evt->rc); |
| 383 | if (evt->type == UWB_EVT_TYPE_NOTIF) | 343 | if (evt->type == UWB_EVT_TYPE_NOTIF) |
| 384 | kfree(evt->notif.rceb); | 344 | kfree(evt->notif.rceb); |
| 385 | kfree(evt); | 345 | kfree(evt); |
| 386 | } | 346 | } |
| 387 | spin_unlock_irqrestore(&uwbd_event_list_lock, flags); | 347 | spin_unlock_irqrestore(&rc->uwbd.event_list_lock, flags); |
| 388 | return; | 348 | return; |
| 389 | } | 349 | } |
| 390 | 350 | ||
| @@ -392,10 +352,8 @@ void uwbd_flush(struct uwb_rc *rc) | |||
| 392 | { | 352 | { |
| 393 | struct uwb_event *evt, *nxt; | 353 | struct uwb_event *evt, *nxt; |
| 394 | 354 | ||
| 395 | mutex_lock(&uwbd_event_mutex); | 355 | spin_lock_irq(&rc->uwbd.event_list_lock); |
| 396 | 356 | list_for_each_entry_safe(evt, nxt, &rc->uwbd.event_list, list_node) { | |
| 397 | spin_lock_irq(&uwbd_event_list_lock); | ||
| 398 | list_for_each_entry_safe(evt, nxt, &uwbd_event_list, list_node) { | ||
| 399 | if (evt->rc == rc) { | 357 | if (evt->rc == rc) { |
| 400 | __uwb_rc_put(rc); | 358 | __uwb_rc_put(rc); |
| 401 | list_del(&evt->list_node); | 359 | list_del(&evt->list_node); |
| @@ -404,7 +362,5 @@ void uwbd_flush(struct uwb_rc *rc) | |||
| 404 | kfree(evt); | 362 | kfree(evt); |
| 405 | } | 363 | } |
| 406 | } | 364 | } |
| 407 | spin_unlock_irq(&uwbd_event_list_lock); | 365 | spin_unlock_irq(&rc->uwbd.event_list_lock); |
| 408 | |||
| 409 | mutex_unlock(&uwbd_event_mutex); | ||
| 410 | } | 366 | } |
diff --git a/drivers/uwb/whc-rc.c b/drivers/uwb/whc-rc.c index 1711deadb11..19a1dd12921 100644 --- a/drivers/uwb/whc-rc.c +++ b/drivers/uwb/whc-rc.c | |||
| @@ -39,7 +39,6 @@ | |||
| 39 | * them to the hw and transfer the replies/notifications back to the | 39 | * them to the hw and transfer the replies/notifications back to the |
| 40 | * UWB stack through the UWB daemon (UWBD). | 40 | * UWB stack through the UWB daemon (UWBD). |
| 41 | */ | 41 | */ |
| 42 | #include <linux/version.h> | ||
| 43 | #include <linux/init.h> | 42 | #include <linux/init.h> |
| 44 | #include <linux/module.h> | 43 | #include <linux/module.h> |
| 45 | #include <linux/pci.h> | 44 | #include <linux/pci.h> |
| @@ -49,10 +48,8 @@ | |||
| 49 | #include <linux/uwb.h> | 48 | #include <linux/uwb.h> |
| 50 | #include <linux/uwb/whci.h> | 49 | #include <linux/uwb/whci.h> |
| 51 | #include <linux/uwb/umc.h> | 50 | #include <linux/uwb/umc.h> |
| 52 | #include "uwb-internal.h" | ||
| 53 | 51 | ||
| 54 | #define D_LOCAL 0 | 52 | #include "uwb-internal.h" |
| 55 | #include <linux/uwb/debug.h> | ||
| 56 | 53 | ||
| 57 | /** | 54 | /** |
| 58 | * Descriptor for an instance of the UWB Radio Control Driver that | 55 | * Descriptor for an instance of the UWB Radio Control Driver that |
| @@ -98,13 +95,8 @@ static int whcrc_cmd(struct uwb_rc *uwb_rc, | |||
| 98 | struct device *dev = &whcrc->umc_dev->dev; | 95 | struct device *dev = &whcrc->umc_dev->dev; |
| 99 | u32 urccmd; | 96 | u32 urccmd; |
| 100 | 97 | ||
| 101 | d_fnstart(3, dev, "(%p, %p, %zu)\n", uwb_rc, cmd, cmd_size); | 98 | if (cmd_size >= 4096) |
| 102 | might_sleep(); | 99 | return -EINVAL; |
| 103 | |||
| 104 | if (cmd_size >= 4096) { | ||
| 105 | result = -E2BIG; | ||
| 106 | goto error; | ||
| 107 | } | ||
| 108 | 100 | ||
| 109 | /* | 101 | /* |
| 110 | * If the URC is halted, then the hardware has reset itself. | 102 | * If the URC is halted, then the hardware has reset itself. |
| @@ -115,16 +107,14 @@ static int whcrc_cmd(struct uwb_rc *uwb_rc, | |||
| 115 | if (le_readl(whcrc->rc_base + URCSTS) & URCSTS_HALTED) { | 107 | if (le_readl(whcrc->rc_base + URCSTS) & URCSTS_HALTED) { |
| 116 | dev_err(dev, "requesting reset of halted radio controller\n"); | 108 | dev_err(dev, "requesting reset of halted radio controller\n"); |
| 117 | uwb_rc_reset_all(uwb_rc); | 109 | uwb_rc_reset_all(uwb_rc); |
| 118 | result = -EIO; | 110 | return -EIO; |
| 119 | goto error; | ||
| 120 | } | 111 | } |
| 121 | 112 | ||
| 122 | result = wait_event_timeout(whcrc->cmd_wq, | 113 | result = wait_event_timeout(whcrc->cmd_wq, |
| 123 | !(le_readl(whcrc->rc_base + URCCMD) & URCCMD_ACTIVE), HZ/2); | 114 | !(le_readl(whcrc->rc_base + URCCMD) & URCCMD_ACTIVE), HZ/2); |
| 124 | if (result == 0) { | 115 | if (result == 0) { |
| 125 | dev_err(dev, "device is not ready to execute commands\n"); | 116 | dev_err(dev, "device is not ready to execute commands\n"); |
| 126 | result = -ETIMEDOUT; | 117 | return -ETIMEDOUT; |
| 127 | goto error; | ||
| 128 | } | 118 | } |
| 129 | 119 | ||
| 130 | memmove(whcrc->cmd_buf, cmd, cmd_size); | 120 | memmove(whcrc->cmd_buf, cmd, cmd_size); |
| @@ -137,10 +127,7 @@ static int whcrc_cmd(struct uwb_rc *uwb_rc, | |||
| 137 | whcrc->rc_base + URCCMD); | 127 | whcrc->rc_base + URCCMD); |
| 138 | spin_unlock(&whcrc->irq_lock); | 128 | spin_unlock(&whcrc->irq_lock); |
| 139 | 129 | ||
| 140 | error: | 130 | return 0; |
| 141 | d_fnend(3, dev, "(%p, %p, %zu) = %d\n", | ||
| 142 | uwb_rc, cmd, cmd_size, result); | ||
| 143 | return result; | ||
| 144 | } | 131 | } |
| 145 | 132 | ||
| 146 | static int whcrc_reset(struct uwb_rc *rc) | 133 | static int whcrc_reset(struct uwb_rc *rc) |
| @@ -167,34 +154,25 @@ static int whcrc_reset(struct uwb_rc *rc) | |||
| 167 | static | 154 | static |
| 168 | void whcrc_enable_events(struct whcrc *whcrc) | 155 | void whcrc_enable_events(struct whcrc *whcrc) |
| 169 | { | 156 | { |
| 170 | struct device *dev = &whcrc->umc_dev->dev; | ||
| 171 | u32 urccmd; | 157 | u32 urccmd; |
| 172 | 158 | ||
| 173 | d_fnstart(4, dev, "(whcrc %p)\n", whcrc); | ||
| 174 | |||
| 175 | le_writeq(whcrc->evt_dma_buf, whcrc->rc_base + URCEVTADDR); | 159 | le_writeq(whcrc->evt_dma_buf, whcrc->rc_base + URCEVTADDR); |
| 176 | 160 | ||
| 177 | spin_lock(&whcrc->irq_lock); | 161 | spin_lock(&whcrc->irq_lock); |
| 178 | urccmd = le_readl(whcrc->rc_base + URCCMD) & ~URCCMD_ACTIVE; | 162 | urccmd = le_readl(whcrc->rc_base + URCCMD) & ~URCCMD_ACTIVE; |
| 179 | le_writel(urccmd | URCCMD_EARV, whcrc->rc_base + URCCMD); | 163 | le_writel(urccmd | URCCMD_EARV, whcrc->rc_base + URCCMD); |
| 180 | spin_unlock(&whcrc->irq_lock); | 164 | spin_unlock(&whcrc->irq_lock); |
| 181 | |||
| 182 | d_fnend(4, dev, "(whcrc %p) = void\n", whcrc); | ||
| 183 | } | 165 | } |
| 184 | 166 | ||
| 185 | static void whcrc_event_work(struct work_struct *work) | 167 | static void whcrc_event_work(struct work_struct *work) |
| 186 | { | 168 | { |
| 187 | struct whcrc *whcrc = container_of(work, struct whcrc, event_work); | 169 | struct whcrc *whcrc = container_of(work, struct whcrc, event_work); |
| 188 | struct device *dev = &whcrc->umc_dev->dev; | ||
| 189 | size_t size; | 170 | size_t size; |
| 190 | u64 urcevtaddr; | 171 | u64 urcevtaddr; |
| 191 | 172 | ||
| 192 | urcevtaddr = le_readq(whcrc->rc_base + URCEVTADDR); | 173 | urcevtaddr = le_readq(whcrc->rc_base + URCEVTADDR); |
| 193 | size = urcevtaddr & URCEVTADDR_OFFSET_MASK; | 174 | size = urcevtaddr & URCEVTADDR_OFFSET_MASK; |
| 194 | 175 | ||
| 195 | d_printf(3, dev, "received %zu octet event\n", size); | ||
| 196 | d_dump(4, dev, whcrc->evt_buf, size > 32 ? 32 : size); | ||
| 197 | |||
| 198 | uwb_rc_neh_grok(whcrc->uwb_rc, whcrc->evt_buf, size); | 176 | uwb_rc_neh_grok(whcrc->uwb_rc, whcrc->evt_buf, size); |
| 199 | whcrc_enable_events(whcrc); | 177 | whcrc_enable_events(whcrc); |
| 200 | } | 178 | } |
| @@ -217,22 +195,15 @@ irqreturn_t whcrc_irq_cb(int irq, void *_whcrc) | |||
| 217 | return IRQ_NONE; | 195 | return IRQ_NONE; |
| 218 | le_writel(urcsts & URCSTS_INT_MASK, whcrc->rc_base + URCSTS); | 196 | le_writel(urcsts & URCSTS_INT_MASK, whcrc->rc_base + URCSTS); |
| 219 | 197 | ||
| 220 | d_printf(4, dev, "acked 0x%08x, urcsts 0x%08x\n", | ||
| 221 | le_readl(whcrc->rc_base + URCSTS), urcsts); | ||
| 222 | |||
| 223 | if (urcsts & URCSTS_HSE) { | 198 | if (urcsts & URCSTS_HSE) { |
| 224 | dev_err(dev, "host system error -- hardware halted\n"); | 199 | dev_err(dev, "host system error -- hardware halted\n"); |
| 225 | /* FIXME: do something sensible here */ | 200 | /* FIXME: do something sensible here */ |
| 226 | goto out; | 201 | goto out; |
| 227 | } | 202 | } |
| 228 | if (urcsts & URCSTS_ER) { | 203 | if (urcsts & URCSTS_ER) |
| 229 | d_printf(3, dev, "ER: event ready\n"); | ||
| 230 | schedule_work(&whcrc->event_work); | 204 | schedule_work(&whcrc->event_work); |
| 231 | } | 205 | if (urcsts & URCSTS_RCI) |
| 232 | if (urcsts & URCSTS_RCI) { | ||
| 233 | d_printf(3, dev, "RCI: ready to execute another command\n"); | ||
| 234 | wake_up_all(&whcrc->cmd_wq); | 206 | wake_up_all(&whcrc->cmd_wq); |
| 235 | } | ||
| 236 | out: | 207 | out: |
| 237 | return IRQ_HANDLED; | 208 | return IRQ_HANDLED; |
| 238 | } | 209 | } |
| @@ -251,8 +222,7 @@ int whcrc_setup_rc_umc(struct whcrc *whcrc) | |||
| 251 | whcrc->area = umc_dev->resource.start; | 222 | whcrc->area = umc_dev->resource.start; |
| 252 | whcrc->rc_len = umc_dev->resource.end - umc_dev->resource.start + 1; | 223 | whcrc->rc_len = umc_dev->resource.end - umc_dev->resource.start + 1; |
| 253 | result = -EBUSY; | 224 | result = -EBUSY; |
| 254 | if (request_mem_region(whcrc->area, whcrc->rc_len, KBUILD_MODNAME) | 225 | if (request_mem_region(whcrc->area, whcrc->rc_len, KBUILD_MODNAME) == NULL) { |
| 255 | == NULL) { | ||
| 256 | dev_err(dev, "can't request URC region (%zu bytes @ 0x%lx): %d\n", | 226 | dev_err(dev, "can't request URC region (%zu bytes @ 0x%lx): %d\n", |
| 257 | whcrc->rc_len, whcrc->area, result); | 227 | whcrc->rc_len, whcrc->area, result); |
| 258 | goto error_request_region; | 228 | goto error_request_region; |
| @@ -287,8 +257,6 @@ int whcrc_setup_rc_umc(struct whcrc *whcrc) | |||
| 287 | dev_err(dev, "Can't allocate evt transfer buffer\n"); | 257 | dev_err(dev, "Can't allocate evt transfer buffer\n"); |
| 288 | goto error_evt_buffer; | 258 | goto error_evt_buffer; |
| 289 | } | 259 | } |
| 290 | d_printf(3, dev, "UWB RC Interface: %zu bytes at 0x%p, irq %u\n", | ||
| 291 | whcrc->rc_len, whcrc->rc_base, umc_dev->irq); | ||
| 292 | return 0; | 260 | return 0; |
| 293 | 261 | ||
| 294 | error_evt_buffer: | 262 | error_evt_buffer: |
| @@ -333,47 +301,23 @@ void whcrc_release_rc_umc(struct whcrc *whcrc) | |||
| 333 | static int whcrc_start_rc(struct uwb_rc *rc) | 301 | static int whcrc_start_rc(struct uwb_rc *rc) |
| 334 | { | 302 | { |
| 335 | struct whcrc *whcrc = rc->priv; | 303 | struct whcrc *whcrc = rc->priv; |
| 336 | int result = 0; | ||
| 337 | struct device *dev = &whcrc->umc_dev->dev; | 304 | struct device *dev = &whcrc->umc_dev->dev; |
| 338 | unsigned long start, duration; | ||
| 339 | 305 | ||
| 340 | /* Reset the thing */ | 306 | /* Reset the thing */ |
| 341 | le_writel(URCCMD_RESET, whcrc->rc_base + URCCMD); | 307 | le_writel(URCCMD_RESET, whcrc->rc_base + URCCMD); |
| 342 | if (d_test(3)) | ||
| 343 | start = jiffies; | ||
| 344 | if (whci_wait_for(dev, whcrc->rc_base + URCCMD, URCCMD_RESET, 0, | 308 | if (whci_wait_for(dev, whcrc->rc_base + URCCMD, URCCMD_RESET, 0, |
| 345 | 5000, "device to reset at init") < 0) { | 309 | 5000, "hardware reset") < 0) |
| 346 | result = -EBUSY; | 310 | return -EBUSY; |
| 347 | goto error; | ||
| 348 | } else if (d_test(3)) { | ||
| 349 | duration = jiffies - start; | ||
| 350 | if (duration > msecs_to_jiffies(40)) | ||
| 351 | dev_err(dev, "Device took %ums to " | ||
| 352 | "reset. MAX expected: 40ms\n", | ||
| 353 | jiffies_to_msecs(duration)); | ||
| 354 | } | ||
| 355 | 311 | ||
| 356 | /* Set the event buffer, start the controller (enable IRQs later) */ | 312 | /* Set the event buffer, start the controller (enable IRQs later) */ |
| 357 | le_writel(0, whcrc->rc_base + URCINTR); | 313 | le_writel(0, whcrc->rc_base + URCINTR); |
| 358 | le_writel(URCCMD_RS, whcrc->rc_base + URCCMD); | 314 | le_writel(URCCMD_RS, whcrc->rc_base + URCCMD); |
| 359 | result = -ETIMEDOUT; | ||
| 360 | if (d_test(3)) | ||
| 361 | start = jiffies; | ||
| 362 | if (whci_wait_for(dev, whcrc->rc_base + URCSTS, URCSTS_HALTED, 0, | 315 | if (whci_wait_for(dev, whcrc->rc_base + URCSTS, URCSTS_HALTED, 0, |
| 363 | 5000, "device to start") < 0) | 316 | 5000, "radio controller start") < 0) |
| 364 | goto error; | 317 | return -ETIMEDOUT; |
| 365 | if (d_test(3)) { | ||
| 366 | duration = jiffies - start; | ||
| 367 | if (duration > msecs_to_jiffies(40)) | ||
| 368 | dev_err(dev, "Device took %ums to start. " | ||
| 369 | "MAX expected: 40ms\n", | ||
| 370 | jiffies_to_msecs(duration)); | ||
| 371 | } | ||
| 372 | whcrc_enable_events(whcrc); | 318 | whcrc_enable_events(whcrc); |
| 373 | result = 0; | ||
| 374 | le_writel(URCINTR_EN_ALL, whcrc->rc_base + URCINTR); | 319 | le_writel(URCINTR_EN_ALL, whcrc->rc_base + URCINTR); |
| 375 | error: | 320 | return 0; |
| 376 | return result; | ||
| 377 | } | 321 | } |
| 378 | 322 | ||
| 379 | 323 | ||
| @@ -395,7 +339,7 @@ void whcrc_stop_rc(struct uwb_rc *rc) | |||
| 395 | 339 | ||
| 396 | le_writel(0, whcrc->rc_base + URCCMD); | 340 | le_writel(0, whcrc->rc_base + URCCMD); |
| 397 | whci_wait_for(&umc_dev->dev, whcrc->rc_base + URCSTS, | 341 | whci_wait_for(&umc_dev->dev, whcrc->rc_base + URCSTS, |
| 398 | URCSTS_HALTED, 0, 40, "URCSTS.HALTED"); | 342 | URCSTS_HALTED, URCSTS_HALTED, 100, "radio controller stop"); |
| 399 | } | 343 | } |
| 400 | 344 | ||
| 401 | static void whcrc_init(struct whcrc *whcrc) | 345 | static void whcrc_init(struct whcrc *whcrc) |
| @@ -421,7 +365,6 @@ int whcrc_probe(struct umc_dev *umc_dev) | |||
| 421 | struct whcrc *whcrc; | 365 | struct whcrc *whcrc; |
| 422 | struct device *dev = &umc_dev->dev; | 366 | struct device *dev = &umc_dev->dev; |
| 423 | 367 | ||
| 424 | d_fnstart(3, dev, "(umc_dev %p)\n", umc_dev); | ||
| 425 | result = -ENOMEM; | 368 | result = -ENOMEM; |
| 426 | uwb_rc = uwb_rc_alloc(); | 369 | uwb_rc = uwb_rc_alloc(); |
| 427 | if (uwb_rc == NULL) { | 370 | if (uwb_rc == NULL) { |
| @@ -453,7 +396,6 @@ int whcrc_probe(struct umc_dev *umc_dev) | |||
| 453 | if (result < 0) | 396 | if (result < 0) |
| 454 | goto error_rc_add; | 397 | goto error_rc_add; |
| 455 | umc_set_drvdata(umc_dev, whcrc); | 398 | umc_set_drvdata(umc_dev, whcrc); |
| 456 | d_fnend(3, dev, "(umc_dev %p) = 0\n", umc_dev); | ||
| 457 | return 0; | 399 | return 0; |
| 458 | 400 | ||
| 459 | error_rc_add: | 401 | error_rc_add: |
| @@ -463,7 +405,6 @@ error_setup_rc_umc: | |||
| 463 | error_alloc: | 405 | error_alloc: |
| 464 | uwb_rc_put(uwb_rc); | 406 | uwb_rc_put(uwb_rc); |
| 465 | error_rc_alloc: | 407 | error_rc_alloc: |
| 466 | d_fnend(3, dev, "(umc_dev %p) = %d\n", umc_dev, result); | ||
| 467 | return result; | 408 | return result; |
| 468 | } | 409 | } |
| 469 | 410 | ||
| @@ -486,7 +427,24 @@ static void whcrc_remove(struct umc_dev *umc_dev) | |||
| 486 | whcrc_release_rc_umc(whcrc); | 427 | whcrc_release_rc_umc(whcrc); |
| 487 | kfree(whcrc); | 428 | kfree(whcrc); |
| 488 | uwb_rc_put(uwb_rc); | 429 | uwb_rc_put(uwb_rc); |
| 489 | d_printf(1, &umc_dev->dev, "freed whcrc %p\n", whcrc); | 430 | } |
| 431 | |||
| 432 | static int whcrc_pre_reset(struct umc_dev *umc) | ||
| 433 | { | ||
| 434 | struct whcrc *whcrc = umc_get_drvdata(umc); | ||
| 435 | struct uwb_rc *uwb_rc = whcrc->uwb_rc; | ||
| 436 | |||
| 437 | uwb_rc_pre_reset(uwb_rc); | ||
| 438 | return 0; | ||
| 439 | } | ||
| 440 | |||
| 441 | static int whcrc_post_reset(struct umc_dev *umc) | ||
| 442 | { | ||
| 443 | struct whcrc *whcrc = umc_get_drvdata(umc); | ||
| 444 | struct uwb_rc *uwb_rc = whcrc->uwb_rc; | ||
| 445 | |||
| 446 | uwb_rc_post_reset(uwb_rc); | ||
| 447 | return 0; | ||
| 490 | } | 448 | } |
| 491 | 449 | ||
| 492 | /* PCI device ID's that we handle [so it gets loaded] */ | 450 | /* PCI device ID's that we handle [so it gets loaded] */ |
| @@ -497,10 +455,12 @@ static struct pci_device_id whcrc_id_table[] = { | |||
| 497 | MODULE_DEVICE_TABLE(pci, whcrc_id_table); | 455 | MODULE_DEVICE_TABLE(pci, whcrc_id_table); |
| 498 | 456 | ||
| 499 | static struct umc_driver whcrc_driver = { | 457 | static struct umc_driver whcrc_driver = { |
| 500 | .name = "whc-rc", | 458 | .name = "whc-rc", |
| 501 | .cap_id = UMC_CAP_ID_WHCI_RC, | 459 | .cap_id = UMC_CAP_ID_WHCI_RC, |
| 502 | .probe = whcrc_probe, | 460 | .probe = whcrc_probe, |
| 503 | .remove = whcrc_remove, | 461 | .remove = whcrc_remove, |
| 462 | .pre_reset = whcrc_pre_reset, | ||
| 463 | .post_reset = whcrc_post_reset, | ||
| 504 | }; | 464 | }; |
| 505 | 465 | ||
| 506 | static int __init whcrc_driver_init(void) | 466 | static int __init whcrc_driver_init(void) |
diff --git a/drivers/uwb/whci.c b/drivers/uwb/whci.c index 3df2388f908..1f8964ed988 100644 --- a/drivers/uwb/whci.c +++ b/drivers/uwb/whci.c | |||
| @@ -67,11 +67,11 @@ int whci_wait_for(struct device *dev, u32 __iomem *reg, u32 mask, u32 result, | |||
| 67 | val = le_readl(reg); | 67 | val = le_readl(reg); |
| 68 | if ((val & mask) == result) | 68 | if ((val & mask) == result) |
| 69 | break; | 69 | break; |
| 70 | msleep(10); | ||
| 71 | if (t >= max_ms) { | 70 | if (t >= max_ms) { |
| 72 | dev_err(dev, "timed out waiting for %s ", tag); | 71 | dev_err(dev, "%s timed out\n", tag); |
| 73 | return -ETIMEDOUT; | 72 | return -ETIMEDOUT; |
| 74 | } | 73 | } |
| 74 | msleep(10); | ||
| 75 | t += 10; | 75 | t += 10; |
| 76 | } | 76 | } |
| 77 | return 0; | 77 | return 0; |
| @@ -111,7 +111,7 @@ static int whci_add_cap(struct whci_card *card, int n) | |||
| 111 | + UWBCAPDATA_TO_OFFSET(capdata); | 111 | + UWBCAPDATA_TO_OFFSET(capdata); |
| 112 | umc->resource.end = umc->resource.start | 112 | umc->resource.end = umc->resource.start |
| 113 | + (n == 0 ? 0x20 : UWBCAPDATA_TO_SIZE(capdata)) - 1; | 113 | + (n == 0 ? 0x20 : UWBCAPDATA_TO_SIZE(capdata)) - 1; |
| 114 | umc->resource.name = umc->dev.bus_id; | 114 | umc->resource.name = dev_name(&umc->dev); |
| 115 | umc->resource.flags = card->pci->resource[bar].flags; | 115 | umc->resource.flags = card->pci->resource[bar].flags; |
| 116 | umc->resource.parent = &card->pci->resource[bar]; | 116 | umc->resource.parent = &card->pci->resource[bar]; |
| 117 | umc->irq = card->pci->irq; | 117 | umc->irq = card->pci->irq; |
diff --git a/drivers/uwb/wlp/eda.c b/drivers/uwb/wlp/eda.c index 10985fa233c..69e02003971 100644 --- a/drivers/uwb/wlp/eda.c +++ b/drivers/uwb/wlp/eda.c | |||
| @@ -51,9 +51,7 @@ | |||
| 51 | * the tag and address of the transmitting neighbor. | 51 | * the tag and address of the transmitting neighbor. |
| 52 | */ | 52 | */ |
| 53 | 53 | ||
| 54 | #define D_LOCAL 5 | ||
| 55 | #include <linux/netdevice.h> | 54 | #include <linux/netdevice.h> |
| 56 | #include <linux/uwb/debug.h> | ||
| 57 | #include <linux/etherdevice.h> | 55 | #include <linux/etherdevice.h> |
| 58 | #include <linux/wlp.h> | 56 | #include <linux/wlp.h> |
| 59 | #include "wlp-internal.h" | 57 | #include "wlp-internal.h" |
| @@ -304,7 +302,6 @@ int wlp_eda_for_virtual(struct wlp_eda *eda, | |||
| 304 | { | 302 | { |
| 305 | int result = 0; | 303 | int result = 0; |
| 306 | struct wlp *wlp = container_of(eda, struct wlp, eda); | 304 | struct wlp *wlp = container_of(eda, struct wlp, eda); |
| 307 | struct device *dev = &wlp->rc->uwb_dev.dev; | ||
| 308 | struct wlp_eda_node *itr; | 305 | struct wlp_eda_node *itr; |
| 309 | unsigned long flags; | 306 | unsigned long flags; |
| 310 | int found = 0; | 307 | int found = 0; |
| @@ -313,26 +310,14 @@ int wlp_eda_for_virtual(struct wlp_eda *eda, | |||
| 313 | list_for_each_entry(itr, &eda->cache, list_node) { | 310 | list_for_each_entry(itr, &eda->cache, list_node) { |
| 314 | if (!memcmp(itr->virt_addr, virt_addr, | 311 | if (!memcmp(itr->virt_addr, virt_addr, |
| 315 | sizeof(itr->virt_addr))) { | 312 | sizeof(itr->virt_addr))) { |
| 316 | d_printf(6, dev, "EDA: looking for %pM hit %02x:%02x " | ||
| 317 | "wss %p tag 0x%02x state %u\n", | ||
| 318 | virt_addr, | ||
| 319 | itr->dev_addr.data[1], | ||
| 320 | itr->dev_addr.data[0], itr->wss, | ||
| 321 | itr->tag, itr->state); | ||
| 322 | result = (*function)(wlp, itr, priv); | 313 | result = (*function)(wlp, itr, priv); |
| 323 | *dev_addr = itr->dev_addr; | 314 | *dev_addr = itr->dev_addr; |
| 324 | found = 1; | 315 | found = 1; |
| 325 | break; | 316 | break; |
| 326 | } else | 317 | } |
| 327 | d_printf(6, dev, "EDA: looking for %pM against %pM miss\n", | ||
| 328 | virt_addr, itr->virt_addr); | ||
| 329 | } | 318 | } |
| 330 | if (!found) { | 319 | if (!found) |
| 331 | if (printk_ratelimit()) | ||
| 332 | dev_err(dev, "EDA: Eth addr %pM not found.\n", | ||
| 333 | virt_addr); | ||
| 334 | result = -ENODEV; | 320 | result = -ENODEV; |
| 335 | } | ||
| 336 | spin_unlock_irqrestore(&eda->lock, flags); | 321 | spin_unlock_irqrestore(&eda->lock, flags); |
| 337 | return result; | 322 | return result; |
| 338 | } | 323 | } |
diff --git a/drivers/uwb/wlp/messages.c b/drivers/uwb/wlp/messages.c index a64cb824171..aa42fcee4c4 100644 --- a/drivers/uwb/wlp/messages.c +++ b/drivers/uwb/wlp/messages.c | |||
| @@ -24,8 +24,7 @@ | |||
| 24 | */ | 24 | */ |
| 25 | 25 | ||
| 26 | #include <linux/wlp.h> | 26 | #include <linux/wlp.h> |
| 27 | #define D_LOCAL 6 | 27 | |
| 28 | #include <linux/uwb/debug.h> | ||
| 29 | #include "wlp-internal.h" | 28 | #include "wlp-internal.h" |
| 30 | 29 | ||
| 31 | static | 30 | static |
| @@ -105,24 +104,18 @@ static inline void wlp_set_attr_hdr(struct wlp_attr_hdr *hdr, unsigned type, | |||
| 105 | #define wlp_set(type, type_code, name) \ | 104 | #define wlp_set(type, type_code, name) \ |
| 106 | static size_t wlp_set_##name(struct wlp_attr_##name *attr, type value) \ | 105 | static size_t wlp_set_##name(struct wlp_attr_##name *attr, type value) \ |
| 107 | { \ | 106 | { \ |
| 108 | d_fnstart(6, NULL, "(attribute %p)\n", attr); \ | ||
| 109 | wlp_set_attr_hdr(&attr->hdr, type_code, \ | 107 | wlp_set_attr_hdr(&attr->hdr, type_code, \ |
| 110 | sizeof(*attr) - sizeof(struct wlp_attr_hdr)); \ | 108 | sizeof(*attr) - sizeof(struct wlp_attr_hdr)); \ |
| 111 | attr->name = value; \ | 109 | attr->name = value; \ |
| 112 | d_dump(6, NULL, attr, sizeof(*attr)); \ | ||
| 113 | d_fnend(6, NULL, "(attribute %p)\n", attr); \ | ||
| 114 | return sizeof(*attr); \ | 110 | return sizeof(*attr); \ |
| 115 | } | 111 | } |
| 116 | 112 | ||
| 117 | #define wlp_pset(type, type_code, name) \ | 113 | #define wlp_pset(type, type_code, name) \ |
| 118 | static size_t wlp_set_##name(struct wlp_attr_##name *attr, type value) \ | 114 | static size_t wlp_set_##name(struct wlp_attr_##name *attr, type value) \ |
| 119 | { \ | 115 | { \ |
| 120 | d_fnstart(6, NULL, "(attribute %p)\n", attr); \ | ||
| 121 | wlp_set_attr_hdr(&attr->hdr, type_code, \ | 116 | wlp_set_attr_hdr(&attr->hdr, type_code, \ |
| 122 | sizeof(*attr) - sizeof(struct wlp_attr_hdr)); \ | 117 | sizeof(*attr) - sizeof(struct wlp_attr_hdr)); \ |
| 123 | attr->name = *value; \ | 118 | attr->name = *value; \ |
| 124 | d_dump(6, NULL, attr, sizeof(*attr)); \ | ||
| 125 | d_fnend(6, NULL, "(attribute %p)\n", attr); \ | ||
| 126 | return sizeof(*attr); \ | 119 | return sizeof(*attr); \ |
| 127 | } | 120 | } |
| 128 | 121 | ||
| @@ -139,11 +132,8 @@ static size_t wlp_set_##name(struct wlp_attr_##name *attr, type value) \ | |||
| 139 | static size_t wlp_set_##name(struct wlp_attr_##name *attr, type value, \ | 132 | static size_t wlp_set_##name(struct wlp_attr_##name *attr, type value, \ |
| 140 | size_t len) \ | 133 | size_t len) \ |
| 141 | { \ | 134 | { \ |
| 142 | d_fnstart(6, NULL, "(attribute %p)\n", attr); \ | ||
| 143 | wlp_set_attr_hdr(&attr->hdr, type_code, len); \ | 135 | wlp_set_attr_hdr(&attr->hdr, type_code, len); \ |
| 144 | memcpy(attr->name, value, len); \ | 136 | memcpy(attr->name, value, len); \ |
| 145 | d_dump(6, NULL, attr, sizeof(*attr) + len); \ | ||
| 146 | d_fnend(6, NULL, "(attribute %p)\n", attr); \ | ||
| 147 | return sizeof(*attr) + len; \ | 137 | return sizeof(*attr) + len; \ |
| 148 | } | 138 | } |
| 149 | 139 | ||
| @@ -182,7 +172,7 @@ static size_t wlp_set_wss_info(struct wlp_attr_wss_info *attr, | |||
| 182 | size_t datalen; | 172 | size_t datalen; |
| 183 | void *ptr = attr->wss_info; | 173 | void *ptr = attr->wss_info; |
| 184 | size_t used = sizeof(*attr); | 174 | size_t used = sizeof(*attr); |
| 185 | d_fnstart(6, NULL, "(attribute %p)\n", attr); | 175 | |
| 186 | datalen = sizeof(struct wlp_wss_info) + strlen(wss->name); | 176 | datalen = sizeof(struct wlp_wss_info) + strlen(wss->name); |
| 187 | wlp_set_attr_hdr(&attr->hdr, WLP_ATTR_WSS_INFO, datalen); | 177 | wlp_set_attr_hdr(&attr->hdr, WLP_ATTR_WSS_INFO, datalen); |
| 188 | used = wlp_set_wssid(ptr, &wss->wssid); | 178 | used = wlp_set_wssid(ptr, &wss->wssid); |
| @@ -190,9 +180,6 @@ static size_t wlp_set_wss_info(struct wlp_attr_wss_info *attr, | |||
| 190 | used += wlp_set_accept_enrl(ptr + used, wss->accept_enroll); | 180 | used += wlp_set_accept_enrl(ptr + used, wss->accept_enroll); |
| 191 | used += wlp_set_wss_sec_status(ptr + used, wss->secure_status); | 181 | used += wlp_set_wss_sec_status(ptr + used, wss->secure_status); |
| 192 | used += wlp_set_wss_bcast(ptr + used, &wss->bcast); | 182 | used += wlp_set_wss_bcast(ptr + used, &wss->bcast); |
| 193 | d_dump(6, NULL, attr, sizeof(*attr) + datalen); | ||
| 194 | d_fnend(6, NULL, "(attribute %p, used %d)\n", | ||
| 195 | attr, (int)(sizeof(*attr) + used)); | ||
| 196 | return sizeof(*attr) + used; | 183 | return sizeof(*attr) + used; |
| 197 | } | 184 | } |
| 198 | 185 | ||
| @@ -414,7 +401,6 @@ static ssize_t wlp_get_wss_info_attrs(struct wlp *wlp, | |||
| 414 | size_t used = 0; | 401 | size_t used = 0; |
| 415 | ssize_t result = -EINVAL; | 402 | ssize_t result = -EINVAL; |
| 416 | 403 | ||
| 417 | d_printf(6, dev, "WLP: WSS info: Retrieving WSS name\n"); | ||
| 418 | result = wlp_get_wss_name(wlp, ptr, info->name, buflen); | 404 | result = wlp_get_wss_name(wlp, ptr, info->name, buflen); |
| 419 | if (result < 0) { | 405 | if (result < 0) { |
| 420 | dev_err(dev, "WLP: unable to obtain WSS name from " | 406 | dev_err(dev, "WLP: unable to obtain WSS name from " |
| @@ -422,7 +408,7 @@ static ssize_t wlp_get_wss_info_attrs(struct wlp *wlp, | |||
| 422 | goto error_parse; | 408 | goto error_parse; |
| 423 | } | 409 | } |
| 424 | used += result; | 410 | used += result; |
| 425 | d_printf(6, dev, "WLP: WSS info: Retrieving accept enroll\n"); | 411 | |
| 426 | result = wlp_get_accept_enrl(wlp, ptr + used, &info->accept_enroll, | 412 | result = wlp_get_accept_enrl(wlp, ptr + used, &info->accept_enroll, |
| 427 | buflen - used); | 413 | buflen - used); |
| 428 | if (result < 0) { | 414 | if (result < 0) { |
| @@ -437,7 +423,7 @@ static ssize_t wlp_get_wss_info_attrs(struct wlp *wlp, | |||
| 437 | goto error_parse; | 423 | goto error_parse; |
| 438 | } | 424 | } |
| 439 | used += result; | 425 | used += result; |
| 440 | d_printf(6, dev, "WLP: WSS info: Retrieving secure status\n"); | 426 | |
| 441 | result = wlp_get_wss_sec_status(wlp, ptr + used, &info->sec_status, | 427 | result = wlp_get_wss_sec_status(wlp, ptr + used, &info->sec_status, |
| 442 | buflen - used); | 428 | buflen - used); |
| 443 | if (result < 0) { | 429 | if (result < 0) { |
| @@ -452,7 +438,7 @@ static ssize_t wlp_get_wss_info_attrs(struct wlp *wlp, | |||
| 452 | goto error_parse; | 438 | goto error_parse; |
| 453 | } | 439 | } |
| 454 | used += result; | 440 | used += result; |
| 455 | d_printf(6, dev, "WLP: WSS info: Retrieving broadcast\n"); | 441 | |
| 456 | result = wlp_get_wss_bcast(wlp, ptr + used, &info->bcast, | 442 | result = wlp_get_wss_bcast(wlp, ptr + used, &info->bcast, |
| 457 | buflen - used); | 443 | buflen - used); |
| 458 | if (result < 0) { | 444 | if (result < 0) { |
| @@ -530,7 +516,7 @@ static ssize_t wlp_get_wss_info(struct wlp *wlp, struct wlp_attr_wss_info *attr, | |||
| 530 | len = result; | 516 | len = result; |
| 531 | used = sizeof(*attr); | 517 | used = sizeof(*attr); |
| 532 | ptr = attr; | 518 | ptr = attr; |
| 533 | d_printf(6, dev, "WLP: WSS info: Retrieving WSSID\n"); | 519 | |
| 534 | result = wlp_get_wssid(wlp, ptr + used, wssid, buflen - used); | 520 | result = wlp_get_wssid(wlp, ptr + used, wssid, buflen - used); |
| 535 | if (result < 0) { | 521 | if (result < 0) { |
| 536 | dev_err(dev, "WLP: unable to obtain WSSID from WSS info.\n"); | 522 | dev_err(dev, "WLP: unable to obtain WSSID from WSS info.\n"); |
| @@ -553,8 +539,6 @@ static ssize_t wlp_get_wss_info(struct wlp *wlp, struct wlp_attr_wss_info *attr, | |||
| 553 | goto out; | 539 | goto out; |
| 554 | } | 540 | } |
| 555 | result = used; | 541 | result = used; |
| 556 | d_printf(6, dev, "WLP: Successfully parsed WLP information " | ||
| 557 | "attribute. used %zu bytes\n", used); | ||
| 558 | out: | 542 | out: |
| 559 | return result; | 543 | return result; |
| 560 | } | 544 | } |
| @@ -598,8 +582,6 @@ static ssize_t wlp_get_all_wss_info(struct wlp *wlp, | |||
| 598 | struct wlp_wssid_e *wssid_e; | 582 | struct wlp_wssid_e *wssid_e; |
| 599 | char buf[WLP_WSS_UUID_STRSIZE]; | 583 | char buf[WLP_WSS_UUID_STRSIZE]; |
| 600 | 584 | ||
| 601 | d_fnstart(6, dev, "wlp %p, attr %p, neighbor %p, wss %p, buflen %d \n", | ||
| 602 | wlp, attr, neighbor, wss, (int)buflen); | ||
| 603 | if (buflen < 0) | 585 | if (buflen < 0) |
| 604 | goto out; | 586 | goto out; |
| 605 | 587 | ||
| @@ -638,8 +620,7 @@ static ssize_t wlp_get_all_wss_info(struct wlp *wlp, | |||
| 638 | wss->accept_enroll = wss_info.accept_enroll; | 620 | wss->accept_enroll = wss_info.accept_enroll; |
| 639 | wss->state = WLP_WSS_STATE_PART_ENROLLED; | 621 | wss->state = WLP_WSS_STATE_PART_ENROLLED; |
| 640 | wlp_wss_uuid_print(buf, sizeof(buf), &wssid); | 622 | wlp_wss_uuid_print(buf, sizeof(buf), &wssid); |
| 641 | d_printf(2, dev, "WLP: Found WSS %s. Enrolling.\n", | 623 | dev_dbg(dev, "WLP: Found WSS %s. Enrolling.\n", buf); |
| 642 | buf); | ||
| 643 | } else { | 624 | } else { |
| 644 | wssid_e = wlp_create_wssid_e(wlp, neighbor); | 625 | wssid_e = wlp_create_wssid_e(wlp, neighbor); |
| 645 | if (wssid_e == NULL) { | 626 | if (wssid_e == NULL) { |
| @@ -660,9 +641,6 @@ error_parse: | |||
| 660 | if (result < 0 && !enroll) /* this was a discovery */ | 641 | if (result < 0 && !enroll) /* this was a discovery */ |
| 661 | wlp_remove_neighbor_tmp_info(neighbor); | 642 | wlp_remove_neighbor_tmp_info(neighbor); |
| 662 | out: | 643 | out: |
| 663 | d_fnend(6, dev, "wlp %p, attr %p, neighbor %p, wss %p, buflen %d, " | ||
| 664 | "result %d \n", wlp, attr, neighbor, wss, (int)buflen, | ||
| 665 | (int)result); | ||
| 666 | return result; | 644 | return result; |
| 667 | 645 | ||
| 668 | } | 646 | } |
| @@ -718,7 +696,6 @@ static int wlp_build_assoc_d1(struct wlp *wlp, struct wlp_wss *wss, | |||
| 718 | struct sk_buff *_skb; | 696 | struct sk_buff *_skb; |
| 719 | void *d1_itr; | 697 | void *d1_itr; |
| 720 | 698 | ||
| 721 | d_fnstart(6, dev, "wlp %p\n", wlp); | ||
| 722 | if (wlp->dev_info == NULL) { | 699 | if (wlp->dev_info == NULL) { |
| 723 | result = __wlp_setup_device_info(wlp); | 700 | result = __wlp_setup_device_info(wlp); |
| 724 | if (result < 0) { | 701 | if (result < 0) { |
| @@ -728,24 +705,6 @@ static int wlp_build_assoc_d1(struct wlp *wlp, struct wlp_wss *wss, | |||
| 728 | } | 705 | } |
| 729 | } | 706 | } |
| 730 | info = wlp->dev_info; | 707 | info = wlp->dev_info; |
| 731 | d_printf(6, dev, "Local properties:\n" | ||
| 732 | "Device name (%d bytes): %s\n" | ||
| 733 | "Model name (%d bytes): %s\n" | ||
| 734 | "Manufacturer (%d bytes): %s\n" | ||
| 735 | "Model number (%d bytes): %s\n" | ||
| 736 | "Serial number (%d bytes): %s\n" | ||
| 737 | "Primary device type: \n" | ||
| 738 | " Category: %d \n" | ||
| 739 | " OUI: %02x:%02x:%02x \n" | ||
| 740 | " OUI Subdivision: %u \n", | ||
| 741 | (int)strlen(info->name), info->name, | ||
| 742 | (int)strlen(info->model_name), info->model_name, | ||
| 743 | (int)strlen(info->manufacturer), info->manufacturer, | ||
| 744 | (int)strlen(info->model_nr), info->model_nr, | ||
| 745 | (int)strlen(info->serial), info->serial, | ||
| 746 | info->prim_dev_type.category, | ||
| 747 | info->prim_dev_type.OUI[0], info->prim_dev_type.OUI[1], | ||
| 748 | info->prim_dev_type.OUI[2], info->prim_dev_type.OUIsubdiv); | ||
| 749 | _skb = dev_alloc_skb(sizeof(*_d1) | 708 | _skb = dev_alloc_skb(sizeof(*_d1) |
| 750 | + sizeof(struct wlp_attr_uuid_e) | 709 | + sizeof(struct wlp_attr_uuid_e) |
| 751 | + sizeof(struct wlp_attr_wss_sel_mthd) | 710 | + sizeof(struct wlp_attr_wss_sel_mthd) |
| @@ -768,7 +727,6 @@ static int wlp_build_assoc_d1(struct wlp *wlp, struct wlp_wss *wss, | |||
| 768 | goto error; | 727 | goto error; |
| 769 | } | 728 | } |
| 770 | _d1 = (void *) _skb->data; | 729 | _d1 = (void *) _skb->data; |
| 771 | d_printf(6, dev, "D1 starts at %p \n", _d1); | ||
| 772 | _d1->hdr.mux_hdr = cpu_to_le16(WLP_PROTOCOL_ID); | 730 | _d1->hdr.mux_hdr = cpu_to_le16(WLP_PROTOCOL_ID); |
| 773 | _d1->hdr.type = WLP_FRAME_ASSOCIATION; | 731 | _d1->hdr.type = WLP_FRAME_ASSOCIATION; |
| 774 | _d1->type = WLP_ASSOC_D1; | 732 | _d1->type = WLP_ASSOC_D1; |
| @@ -791,25 +749,8 @@ static int wlp_build_assoc_d1(struct wlp *wlp, struct wlp_wss *wss, | |||
| 791 | used += wlp_set_prim_dev_type(d1_itr + used, &info->prim_dev_type); | 749 | used += wlp_set_prim_dev_type(d1_itr + used, &info->prim_dev_type); |
| 792 | used += wlp_set_wlp_assc_err(d1_itr + used, WLP_ASSOC_ERROR_NONE); | 750 | used += wlp_set_wlp_assc_err(d1_itr + used, WLP_ASSOC_ERROR_NONE); |
| 793 | skb_put(_skb, sizeof(*_d1) + used); | 751 | skb_put(_skb, sizeof(*_d1) + used); |
| 794 | d_printf(6, dev, "D1 message:\n"); | ||
| 795 | d_dump(6, dev, _d1, sizeof(*_d1) | ||
| 796 | + sizeof(struct wlp_attr_uuid_e) | ||
| 797 | + sizeof(struct wlp_attr_wss_sel_mthd) | ||
| 798 | + sizeof(struct wlp_attr_dev_name) | ||
| 799 | + strlen(info->name) | ||
| 800 | + sizeof(struct wlp_attr_manufacturer) | ||
| 801 | + strlen(info->manufacturer) | ||
| 802 | + sizeof(struct wlp_attr_model_name) | ||
| 803 | + strlen(info->model_name) | ||
| 804 | + sizeof(struct wlp_attr_model_nr) | ||
| 805 | + strlen(info->model_nr) | ||
| 806 | + sizeof(struct wlp_attr_serial) | ||
| 807 | + strlen(info->serial) | ||
| 808 | + sizeof(struct wlp_attr_prim_dev_type) | ||
| 809 | + sizeof(struct wlp_attr_wlp_assc_err)); | ||
| 810 | *skb = _skb; | 752 | *skb = _skb; |
| 811 | error: | 753 | error: |
| 812 | d_fnend(6, dev, "wlp %p, result = %d\n", wlp, result); | ||
| 813 | return result; | 754 | return result; |
| 814 | } | 755 | } |
| 815 | 756 | ||
| @@ -837,7 +778,6 @@ int wlp_build_assoc_d2(struct wlp *wlp, struct wlp_wss *wss, | |||
| 837 | void *d2_itr; | 778 | void *d2_itr; |
| 838 | size_t mem_needed; | 779 | size_t mem_needed; |
| 839 | 780 | ||
| 840 | d_fnstart(6, dev, "wlp %p\n", wlp); | ||
| 841 | if (wlp->dev_info == NULL) { | 781 | if (wlp->dev_info == NULL) { |
| 842 | result = __wlp_setup_device_info(wlp); | 782 | result = __wlp_setup_device_info(wlp); |
| 843 | if (result < 0) { | 783 | if (result < 0) { |
| @@ -847,24 +787,6 @@ int wlp_build_assoc_d2(struct wlp *wlp, struct wlp_wss *wss, | |||
| 847 | } | 787 | } |
| 848 | } | 788 | } |
| 849 | info = wlp->dev_info; | 789 | info = wlp->dev_info; |
| 850 | d_printf(6, dev, "Local properties:\n" | ||
| 851 | "Device name (%d bytes): %s\n" | ||
| 852 | "Model name (%d bytes): %s\n" | ||
| 853 | "Manufacturer (%d bytes): %s\n" | ||
| 854 | "Model number (%d bytes): %s\n" | ||
| 855 | "Serial number (%d bytes): %s\n" | ||
| 856 | "Primary device type: \n" | ||
| 857 | " Category: %d \n" | ||
| 858 | " OUI: %02x:%02x:%02x \n" | ||
| 859 | " OUI Subdivision: %u \n", | ||
| 860 | (int)strlen(info->name), info->name, | ||
| 861 | (int)strlen(info->model_name), info->model_name, | ||
| 862 | (int)strlen(info->manufacturer), info->manufacturer, | ||
| 863 | (int)strlen(info->model_nr), info->model_nr, | ||
| 864 | (int)strlen(info->serial), info->serial, | ||
| 865 | info->prim_dev_type.category, | ||
| 866 | info->prim_dev_type.OUI[0], info->prim_dev_type.OUI[1], | ||
| 867 | info->prim_dev_type.OUI[2], info->prim_dev_type.OUIsubdiv); | ||
| 868 | mem_needed = sizeof(*_d2) | 790 | mem_needed = sizeof(*_d2) |
| 869 | + sizeof(struct wlp_attr_uuid_e) | 791 | + sizeof(struct wlp_attr_uuid_e) |
| 870 | + sizeof(struct wlp_attr_uuid_r) | 792 | + sizeof(struct wlp_attr_uuid_r) |
| @@ -892,7 +814,6 @@ int wlp_build_assoc_d2(struct wlp *wlp, struct wlp_wss *wss, | |||
| 892 | goto error; | 814 | goto error; |
| 893 | } | 815 | } |
| 894 | _d2 = (void *) _skb->data; | 816 | _d2 = (void *) _skb->data; |
| 895 | d_printf(6, dev, "D2 starts at %p \n", _d2); | ||
| 896 | _d2->hdr.mux_hdr = cpu_to_le16(WLP_PROTOCOL_ID); | 817 | _d2->hdr.mux_hdr = cpu_to_le16(WLP_PROTOCOL_ID); |
| 897 | _d2->hdr.type = WLP_FRAME_ASSOCIATION; | 818 | _d2->hdr.type = WLP_FRAME_ASSOCIATION; |
| 898 | _d2->type = WLP_ASSOC_D2; | 819 | _d2->type = WLP_ASSOC_D2; |
| @@ -917,11 +838,8 @@ int wlp_build_assoc_d2(struct wlp *wlp, struct wlp_wss *wss, | |||
| 917 | used += wlp_set_prim_dev_type(d2_itr + used, &info->prim_dev_type); | 838 | used += wlp_set_prim_dev_type(d2_itr + used, &info->prim_dev_type); |
| 918 | used += wlp_set_wlp_assc_err(d2_itr + used, WLP_ASSOC_ERROR_NONE); | 839 | used += wlp_set_wlp_assc_err(d2_itr + used, WLP_ASSOC_ERROR_NONE); |
| 919 | skb_put(_skb, sizeof(*_d2) + used); | 840 | skb_put(_skb, sizeof(*_d2) + used); |
| 920 | d_printf(6, dev, "D2 message:\n"); | ||
| 921 | d_dump(6, dev, _d2, mem_needed); | ||
| 922 | *skb = _skb; | 841 | *skb = _skb; |
| 923 | error: | 842 | error: |
| 924 | d_fnend(6, dev, "wlp %p, result = %d\n", wlp, result); | ||
| 925 | return result; | 843 | return result; |
| 926 | } | 844 | } |
| 927 | 845 | ||
| @@ -947,7 +865,6 @@ int wlp_build_assoc_f0(struct wlp *wlp, struct sk_buff **skb, | |||
| 947 | struct sk_buff *_skb; | 865 | struct sk_buff *_skb; |
| 948 | struct wlp_nonce tmp; | 866 | struct wlp_nonce tmp; |
| 949 | 867 | ||
| 950 | d_fnstart(6, dev, "wlp %p\n", wlp); | ||
| 951 | _skb = dev_alloc_skb(sizeof(*f0)); | 868 | _skb = dev_alloc_skb(sizeof(*f0)); |
| 952 | if (_skb == NULL) { | 869 | if (_skb == NULL) { |
| 953 | dev_err(dev, "WLP: Unable to allocate memory for F0 " | 870 | dev_err(dev, "WLP: Unable to allocate memory for F0 " |
| @@ -955,7 +872,6 @@ int wlp_build_assoc_f0(struct wlp *wlp, struct sk_buff **skb, | |||
| 955 | goto error_alloc; | 872 | goto error_alloc; |
| 956 | } | 873 | } |
| 957 | f0 = (void *) _skb->data; | 874 | f0 = (void *) _skb->data; |
| 958 | d_printf(6, dev, "F0 starts at %p \n", f0); | ||
| 959 | f0->f0_hdr.hdr.mux_hdr = cpu_to_le16(WLP_PROTOCOL_ID); | 875 | f0->f0_hdr.hdr.mux_hdr = cpu_to_le16(WLP_PROTOCOL_ID); |
| 960 | f0->f0_hdr.hdr.type = WLP_FRAME_ASSOCIATION; | 876 | f0->f0_hdr.hdr.type = WLP_FRAME_ASSOCIATION; |
| 961 | f0->f0_hdr.type = WLP_ASSOC_F0; | 877 | f0->f0_hdr.type = WLP_ASSOC_F0; |
| @@ -969,7 +885,6 @@ int wlp_build_assoc_f0(struct wlp *wlp, struct sk_buff **skb, | |||
| 969 | *skb = _skb; | 885 | *skb = _skb; |
| 970 | result = 0; | 886 | result = 0; |
| 971 | error_alloc: | 887 | error_alloc: |
| 972 | d_fnend(6, dev, "wlp %p, result %d \n", wlp, result); | ||
| 973 | return result; | 888 | return result; |
| 974 | } | 889 | } |
| 975 | 890 | ||
| @@ -1242,12 +1157,9 @@ void wlp_handle_d1_frame(struct work_struct *ws) | |||
| 1242 | enum wlp_wss_sel_mthd sel_mthd = 0; | 1157 | enum wlp_wss_sel_mthd sel_mthd = 0; |
| 1243 | struct wlp_device_info dev_info; | 1158 | struct wlp_device_info dev_info; |
| 1244 | enum wlp_assc_error assc_err; | 1159 | enum wlp_assc_error assc_err; |
| 1245 | char uuid[WLP_WSS_UUID_STRSIZE]; | ||
| 1246 | struct sk_buff *resp = NULL; | 1160 | struct sk_buff *resp = NULL; |
| 1247 | 1161 | ||
| 1248 | /* Parse D1 frame */ | 1162 | /* Parse D1 frame */ |
| 1249 | d_fnstart(6, dev, "WLP: handle D1 frame. wlp = %p, skb = %p\n", | ||
| 1250 | wlp, skb); | ||
| 1251 | mutex_lock(&wss->mutex); | 1163 | mutex_lock(&wss->mutex); |
| 1252 | mutex_lock(&wlp->mutex); /* to access wlp->uuid */ | 1164 | mutex_lock(&wlp->mutex); /* to access wlp->uuid */ |
| 1253 | memset(&dev_info, 0, sizeof(dev_info)); | 1165 | memset(&dev_info, 0, sizeof(dev_info)); |
| @@ -1258,30 +1170,6 @@ void wlp_handle_d1_frame(struct work_struct *ws) | |||
| 1258 | kfree_skb(skb); | 1170 | kfree_skb(skb); |
| 1259 | goto out; | 1171 | goto out; |
| 1260 | } | 1172 | } |
| 1261 | wlp_wss_uuid_print(uuid, sizeof(uuid), &uuid_e); | ||
| 1262 | d_printf(6, dev, "From D1 frame:\n" | ||
| 1263 | "UUID-E: %s\n" | ||
| 1264 | "Selection method: %d\n" | ||
| 1265 | "Device name (%d bytes): %s\n" | ||
| 1266 | "Model name (%d bytes): %s\n" | ||
| 1267 | "Manufacturer (%d bytes): %s\n" | ||
| 1268 | "Model number (%d bytes): %s\n" | ||
| 1269 | "Serial number (%d bytes): %s\n" | ||
| 1270 | "Primary device type: \n" | ||
| 1271 | " Category: %d \n" | ||
| 1272 | " OUI: %02x:%02x:%02x \n" | ||
| 1273 | " OUI Subdivision: %u \n", | ||
| 1274 | uuid, sel_mthd, | ||
| 1275 | (int)strlen(dev_info.name), dev_info.name, | ||
| 1276 | (int)strlen(dev_info.model_name), dev_info.model_name, | ||
| 1277 | (int)strlen(dev_info.manufacturer), dev_info.manufacturer, | ||
| 1278 | (int)strlen(dev_info.model_nr), dev_info.model_nr, | ||
| 1279 | (int)strlen(dev_info.serial), dev_info.serial, | ||
| 1280 | dev_info.prim_dev_type.category, | ||
| 1281 | dev_info.prim_dev_type.OUI[0], | ||
| 1282 | dev_info.prim_dev_type.OUI[1], | ||
| 1283 | dev_info.prim_dev_type.OUI[2], | ||
| 1284 | dev_info.prim_dev_type.OUIsubdiv); | ||
| 1285 | 1173 | ||
| 1286 | kfree_skb(skb); | 1174 | kfree_skb(skb); |
| 1287 | if (!wlp_uuid_is_set(&wlp->uuid)) { | 1175 | if (!wlp_uuid_is_set(&wlp->uuid)) { |
| @@ -1316,7 +1204,6 @@ out: | |||
| 1316 | kfree(frame_ctx); | 1204 | kfree(frame_ctx); |
| 1317 | mutex_unlock(&wlp->mutex); | 1205 | mutex_unlock(&wlp->mutex); |
| 1318 | mutex_unlock(&wss->mutex); | 1206 | mutex_unlock(&wss->mutex); |
| 1319 | d_fnend(6, dev, "WLP: handle D1 frame. wlp = %p\n", wlp); | ||
| 1320 | } | 1207 | } |
| 1321 | 1208 | ||
| 1322 | /** | 1209 | /** |
| @@ -1546,10 +1433,8 @@ int wlp_parse_c3c4_frame(struct wlp *wlp, struct sk_buff *skb, | |||
| 1546 | void *ptr = skb->data; | 1433 | void *ptr = skb->data; |
| 1547 | size_t len = skb->len; | 1434 | size_t len = skb->len; |
| 1548 | size_t used; | 1435 | size_t used; |
| 1549 | char buf[WLP_WSS_UUID_STRSIZE]; | ||
| 1550 | struct wlp_frame_assoc *assoc = ptr; | 1436 | struct wlp_frame_assoc *assoc = ptr; |
| 1551 | 1437 | ||
| 1552 | d_fnstart(6, dev, "wlp %p, skb %p \n", wlp, skb); | ||
| 1553 | used = sizeof(*assoc); | 1438 | used = sizeof(*assoc); |
| 1554 | result = wlp_get_wssid(wlp, ptr + used, wssid, len - used); | 1439 | result = wlp_get_wssid(wlp, ptr + used, wssid, len - used); |
| 1555 | if (result < 0) { | 1440 | if (result < 0) { |
| @@ -1572,14 +1457,7 @@ int wlp_parse_c3c4_frame(struct wlp *wlp, struct sk_buff *skb, | |||
| 1572 | wlp_assoc_frame_str(assoc->type)); | 1457 | wlp_assoc_frame_str(assoc->type)); |
| 1573 | goto error_parse; | 1458 | goto error_parse; |
| 1574 | } | 1459 | } |
| 1575 | wlp_wss_uuid_print(buf, sizeof(buf), wssid); | ||
| 1576 | d_printf(6, dev, "WLP: parsed: WSSID %s, tag 0x%02x, virt " | ||
| 1577 | "%02x:%02x:%02x:%02x:%02x:%02x \n", buf, *tag, | ||
| 1578 | virt_addr->data[0], virt_addr->data[1], virt_addr->data[2], | ||
| 1579 | virt_addr->data[3], virt_addr->data[4], virt_addr->data[5]); | ||
| 1580 | |||
| 1581 | error_parse: | 1460 | error_parse: |
| 1582 | d_fnend(6, dev, "wlp %p, skb %p, result = %d \n", wlp, skb, result); | ||
| 1583 | return result; | 1461 | return result; |
| 1584 | } | 1462 | } |
| 1585 | 1463 | ||
| @@ -1600,7 +1478,6 @@ int wlp_build_assoc_c1c2(struct wlp *wlp, struct wlp_wss *wss, | |||
| 1600 | } *c; | 1478 | } *c; |
| 1601 | struct sk_buff *_skb; | 1479 | struct sk_buff *_skb; |
| 1602 | 1480 | ||
| 1603 | d_fnstart(6, dev, "wlp %p, wss %p \n", wlp, wss); | ||
| 1604 | _skb = dev_alloc_skb(sizeof(*c)); | 1481 | _skb = dev_alloc_skb(sizeof(*c)); |
| 1605 | if (_skb == NULL) { | 1482 | if (_skb == NULL) { |
| 1606 | dev_err(dev, "WLP: Unable to allocate memory for C1/C2 " | 1483 | dev_err(dev, "WLP: Unable to allocate memory for C1/C2 " |
| @@ -1608,7 +1485,6 @@ int wlp_build_assoc_c1c2(struct wlp *wlp, struct wlp_wss *wss, | |||
| 1608 | goto error_alloc; | 1485 | goto error_alloc; |
| 1609 | } | 1486 | } |
| 1610 | c = (void *) _skb->data; | 1487 | c = (void *) _skb->data; |
| 1611 | d_printf(6, dev, "C1/C2 starts at %p \n", c); | ||
| 1612 | c->c_hdr.hdr.mux_hdr = cpu_to_le16(WLP_PROTOCOL_ID); | 1488 | c->c_hdr.hdr.mux_hdr = cpu_to_le16(WLP_PROTOCOL_ID); |
| 1613 | c->c_hdr.hdr.type = WLP_FRAME_ASSOCIATION; | 1489 | c->c_hdr.hdr.type = WLP_FRAME_ASSOCIATION; |
| 1614 | c->c_hdr.type = type; | 1490 | c->c_hdr.type = type; |
| @@ -1616,12 +1492,9 @@ int wlp_build_assoc_c1c2(struct wlp *wlp, struct wlp_wss *wss, | |||
| 1616 | wlp_set_msg_type(&c->c_hdr.msg_type, type); | 1492 | wlp_set_msg_type(&c->c_hdr.msg_type, type); |
| 1617 | wlp_set_wssid(&c->wssid, &wss->wssid); | 1493 | wlp_set_wssid(&c->wssid, &wss->wssid); |
| 1618 | skb_put(_skb, sizeof(*c)); | 1494 | skb_put(_skb, sizeof(*c)); |
| 1619 | d_printf(6, dev, "C1/C2 message:\n"); | ||
| 1620 | d_dump(6, dev, c, sizeof(*c)); | ||
| 1621 | *skb = _skb; | 1495 | *skb = _skb; |
| 1622 | result = 0; | 1496 | result = 0; |
| 1623 | error_alloc: | 1497 | error_alloc: |
| 1624 | d_fnend(6, dev, "wlp %p, wss %p, result %d \n", wlp, wss, result); | ||
| 1625 | return result; | 1498 | return result; |
| 1626 | } | 1499 | } |
| 1627 | 1500 | ||
| @@ -1660,7 +1533,6 @@ int wlp_build_assoc_c3c4(struct wlp *wlp, struct wlp_wss *wss, | |||
| 1660 | } *c; | 1533 | } *c; |
| 1661 | struct sk_buff *_skb; | 1534 | struct sk_buff *_skb; |
| 1662 | 1535 | ||
| 1663 | d_fnstart(6, dev, "wlp %p, wss %p \n", wlp, wss); | ||
| 1664 | _skb = dev_alloc_skb(sizeof(*c)); | 1536 | _skb = dev_alloc_skb(sizeof(*c)); |
| 1665 | if (_skb == NULL) { | 1537 | if (_skb == NULL) { |
| 1666 | dev_err(dev, "WLP: Unable to allocate memory for C3/C4 " | 1538 | dev_err(dev, "WLP: Unable to allocate memory for C3/C4 " |
| @@ -1668,7 +1540,6 @@ int wlp_build_assoc_c3c4(struct wlp *wlp, struct wlp_wss *wss, | |||
| 1668 | goto error_alloc; | 1540 | goto error_alloc; |
| 1669 | } | 1541 | } |
| 1670 | c = (void *) _skb->data; | 1542 | c = (void *) _skb->data; |
| 1671 | d_printf(6, dev, "C3/C4 starts at %p \n", c); | ||
| 1672 | c->c_hdr.hdr.mux_hdr = cpu_to_le16(WLP_PROTOCOL_ID); | 1543 | c->c_hdr.hdr.mux_hdr = cpu_to_le16(WLP_PROTOCOL_ID); |
| 1673 | c->c_hdr.hdr.type = WLP_FRAME_ASSOCIATION; | 1544 | c->c_hdr.hdr.type = WLP_FRAME_ASSOCIATION; |
| 1674 | c->c_hdr.type = type; | 1545 | c->c_hdr.type = type; |
| @@ -1678,12 +1549,9 @@ int wlp_build_assoc_c3c4(struct wlp *wlp, struct wlp_wss *wss, | |||
| 1678 | wlp_set_wss_tag(&c->wss_tag, wss->tag); | 1549 | wlp_set_wss_tag(&c->wss_tag, wss->tag); |
| 1679 | wlp_set_wss_virt(&c->wss_virt, &wss->virtual_addr); | 1550 | wlp_set_wss_virt(&c->wss_virt, &wss->virtual_addr); |
| 1680 | skb_put(_skb, sizeof(*c)); | 1551 | skb_put(_skb, sizeof(*c)); |
| 1681 | d_printf(6, dev, "C3/C4 message:\n"); | ||
| 1682 | d_dump(6, dev, c, sizeof(*c)); | ||
| 1683 | *skb = _skb; | 1552 | *skb = _skb; |
| 1684 | result = 0; | 1553 | result = 0; |
| 1685 | error_alloc: | 1554 | error_alloc: |
| 1686 | d_fnend(6, dev, "wlp %p, wss %p, result %d \n", wlp, wss, result); | ||
| 1687 | return result; | 1555 | return result; |
| 1688 | } | 1556 | } |
| 1689 | 1557 | ||
| @@ -1709,10 +1577,7 @@ static int wlp_send_assoc_##type(struct wlp *wlp, struct wlp_wss *wss, \ | |||
| 1709 | struct device *dev = &wlp->rc->uwb_dev.dev; \ | 1577 | struct device *dev = &wlp->rc->uwb_dev.dev; \ |
| 1710 | int result; \ | 1578 | int result; \ |
| 1711 | struct sk_buff *skb = NULL; \ | 1579 | struct sk_buff *skb = NULL; \ |
| 1712 | d_fnstart(6, dev, "wlp %p, wss %p, neighbor: %02x:%02x\n", \ | 1580 | \ |
| 1713 | wlp, wss, dev_addr->data[1], dev_addr->data[0]); \ | ||
| 1714 | d_printf(6, dev, "WLP: Constructing %s frame. \n", \ | ||
| 1715 | wlp_assoc_frame_str(id)); \ | ||
| 1716 | /* Build the frame */ \ | 1581 | /* Build the frame */ \ |
| 1717 | result = wlp_build_assoc_##type(wlp, wss, &skb); \ | 1582 | result = wlp_build_assoc_##type(wlp, wss, &skb); \ |
| 1718 | if (result < 0) { \ | 1583 | if (result < 0) { \ |
| @@ -1721,9 +1586,6 @@ static int wlp_send_assoc_##type(struct wlp *wlp, struct wlp_wss *wss, \ | |||
| 1721 | goto error_build_assoc; \ | 1586 | goto error_build_assoc; \ |
| 1722 | } \ | 1587 | } \ |
| 1723 | /* Send the frame */ \ | 1588 | /* Send the frame */ \ |
| 1724 | d_printf(6, dev, "Transmitting %s frame to %02x:%02x \n", \ | ||
| 1725 | wlp_assoc_frame_str(id), \ | ||
| 1726 | dev_addr->data[1], dev_addr->data[0]); \ | ||
| 1727 | BUG_ON(wlp->xmit_frame == NULL); \ | 1589 | BUG_ON(wlp->xmit_frame == NULL); \ |
| 1728 | result = wlp->xmit_frame(wlp, skb, dev_addr); \ | 1590 | result = wlp->xmit_frame(wlp, skb, dev_addr); \ |
| 1729 | if (result < 0) { \ | 1591 | if (result < 0) { \ |
| @@ -1740,8 +1602,6 @@ error_xmit: \ | |||
| 1740 | /* We could try again ... */ \ | 1602 | /* We could try again ... */ \ |
| 1741 | dev_kfree_skb_any(skb);/*we need to free if tx fails*/ \ | 1603 | dev_kfree_skb_any(skb);/*we need to free if tx fails*/ \ |
| 1742 | error_build_assoc: \ | 1604 | error_build_assoc: \ |
| 1743 | d_fnend(6, dev, "wlp %p, wss %p, neighbor: %02x:%02x\n", \ | ||
| 1744 | wlp, wss, dev_addr->data[1], dev_addr->data[0]); \ | ||
| 1745 | return result; \ | 1605 | return result; \ |
| 1746 | } | 1606 | } |
| 1747 | 1607 | ||
| @@ -1794,12 +1654,9 @@ void wlp_handle_c1_frame(struct work_struct *ws) | |||
| 1794 | struct uwb_dev_addr *src = &frame_ctx->src; | 1654 | struct uwb_dev_addr *src = &frame_ctx->src; |
| 1795 | int result; | 1655 | int result; |
| 1796 | struct wlp_uuid wssid; | 1656 | struct wlp_uuid wssid; |
| 1797 | char buf[WLP_WSS_UUID_STRSIZE]; | ||
| 1798 | struct sk_buff *resp = NULL; | 1657 | struct sk_buff *resp = NULL; |
| 1799 | 1658 | ||
| 1800 | /* Parse C1 frame */ | 1659 | /* Parse C1 frame */ |
| 1801 | d_fnstart(6, dev, "WLP: handle C1 frame. wlp = %p, c1 = %p\n", | ||
| 1802 | wlp, c1); | ||
| 1803 | mutex_lock(&wss->mutex); | 1660 | mutex_lock(&wss->mutex); |
| 1804 | result = wlp_get_wssid(wlp, (void *)c1 + sizeof(*c1), &wssid, | 1661 | result = wlp_get_wssid(wlp, (void *)c1 + sizeof(*c1), &wssid, |
| 1805 | len - sizeof(*c1)); | 1662 | len - sizeof(*c1)); |
| @@ -1807,12 +1664,8 @@ void wlp_handle_c1_frame(struct work_struct *ws) | |||
| 1807 | dev_err(dev, "WLP: unable to obtain WSSID from C1 frame.\n"); | 1664 | dev_err(dev, "WLP: unable to obtain WSSID from C1 frame.\n"); |
| 1808 | goto out; | 1665 | goto out; |
| 1809 | } | 1666 | } |
| 1810 | wlp_wss_uuid_print(buf, sizeof(buf), &wssid); | ||
| 1811 | d_printf(6, dev, "Received C1 frame with WSSID %s \n", buf); | ||
| 1812 | if (!memcmp(&wssid, &wss->wssid, sizeof(wssid)) | 1667 | if (!memcmp(&wssid, &wss->wssid, sizeof(wssid)) |
| 1813 | && wss->state == WLP_WSS_STATE_ACTIVE) { | 1668 | && wss->state == WLP_WSS_STATE_ACTIVE) { |
| 1814 | d_printf(6, dev, "WSSID from C1 frame is known locally " | ||
| 1815 | "and is active\n"); | ||
| 1816 | /* Construct C2 frame */ | 1669 | /* Construct C2 frame */ |
| 1817 | result = wlp_build_assoc_c2(wlp, wss, &resp); | 1670 | result = wlp_build_assoc_c2(wlp, wss, &resp); |
| 1818 | if (result < 0) { | 1671 | if (result < 0) { |
| @@ -1820,8 +1673,6 @@ void wlp_handle_c1_frame(struct work_struct *ws) | |||
| 1820 | goto out; | 1673 | goto out; |
| 1821 | } | 1674 | } |
| 1822 | } else { | 1675 | } else { |
| 1823 | d_printf(6, dev, "WSSID from C1 frame is not known locally " | ||
| 1824 | "or is not active\n"); | ||
| 1825 | /* Construct F0 frame */ | 1676 | /* Construct F0 frame */ |
| 1826 | result = wlp_build_assoc_f0(wlp, &resp, WLP_ASSOC_ERROR_INV); | 1677 | result = wlp_build_assoc_f0(wlp, &resp, WLP_ASSOC_ERROR_INV); |
| 1827 | if (result < 0) { | 1678 | if (result < 0) { |
| @@ -1830,8 +1681,6 @@ void wlp_handle_c1_frame(struct work_struct *ws) | |||
| 1830 | } | 1681 | } |
| 1831 | } | 1682 | } |
| 1832 | /* Send C2 frame */ | 1683 | /* Send C2 frame */ |
| 1833 | d_printf(6, dev, "Transmitting response (C2/F0) frame to %02x:%02x \n", | ||
| 1834 | src->data[1], src->data[0]); | ||
| 1835 | BUG_ON(wlp->xmit_frame == NULL); | 1684 | BUG_ON(wlp->xmit_frame == NULL); |
| 1836 | result = wlp->xmit_frame(wlp, resp, src); | 1685 | result = wlp->xmit_frame(wlp, resp, src); |
| 1837 | if (result < 0) { | 1686 | if (result < 0) { |
| @@ -1846,7 +1695,6 @@ out: | |||
| 1846 | kfree_skb(frame_ctx->skb); | 1695 | kfree_skb(frame_ctx->skb); |
| 1847 | kfree(frame_ctx); | 1696 | kfree(frame_ctx); |
| 1848 | mutex_unlock(&wss->mutex); | 1697 | mutex_unlock(&wss->mutex); |
| 1849 | d_fnend(6, dev, "WLP: handle C1 frame. wlp = %p\n", wlp); | ||
| 1850 | } | 1698 | } |
| 1851 | 1699 | ||
| 1852 | /** | 1700 | /** |
| @@ -1868,27 +1716,20 @@ void wlp_handle_c3_frame(struct work_struct *ws) | |||
| 1868 | struct sk_buff *skb = frame_ctx->skb; | 1716 | struct sk_buff *skb = frame_ctx->skb; |
| 1869 | struct uwb_dev_addr *src = &frame_ctx->src; | 1717 | struct uwb_dev_addr *src = &frame_ctx->src; |
| 1870 | int result; | 1718 | int result; |
| 1871 | char buf[WLP_WSS_UUID_STRSIZE]; | ||
| 1872 | struct sk_buff *resp = NULL; | 1719 | struct sk_buff *resp = NULL; |
| 1873 | struct wlp_uuid wssid; | 1720 | struct wlp_uuid wssid; |
| 1874 | u8 tag; | 1721 | u8 tag; |
| 1875 | struct uwb_mac_addr virt_addr; | 1722 | struct uwb_mac_addr virt_addr; |
| 1876 | 1723 | ||
| 1877 | /* Parse C3 frame */ | 1724 | /* Parse C3 frame */ |
| 1878 | d_fnstart(6, dev, "WLP: handle C3 frame. wlp = %p, skb = %p\n", | ||
| 1879 | wlp, skb); | ||
| 1880 | mutex_lock(&wss->mutex); | 1725 | mutex_lock(&wss->mutex); |
| 1881 | result = wlp_parse_c3c4_frame(wlp, skb, &wssid, &tag, &virt_addr); | 1726 | result = wlp_parse_c3c4_frame(wlp, skb, &wssid, &tag, &virt_addr); |
| 1882 | if (result < 0) { | 1727 | if (result < 0) { |
| 1883 | dev_err(dev, "WLP: unable to obtain values from C3 frame.\n"); | 1728 | dev_err(dev, "WLP: unable to obtain values from C3 frame.\n"); |
| 1884 | goto out; | 1729 | goto out; |
| 1885 | } | 1730 | } |
| 1886 | wlp_wss_uuid_print(buf, sizeof(buf), &wssid); | ||
| 1887 | d_printf(6, dev, "Received C3 frame with WSSID %s \n", buf); | ||
| 1888 | if (!memcmp(&wssid, &wss->wssid, sizeof(wssid)) | 1731 | if (!memcmp(&wssid, &wss->wssid, sizeof(wssid)) |
| 1889 | && wss->state >= WLP_WSS_STATE_ACTIVE) { | 1732 | && wss->state >= WLP_WSS_STATE_ACTIVE) { |
| 1890 | d_printf(6, dev, "WSSID from C3 frame is known locally " | ||
| 1891 | "and is active\n"); | ||
| 1892 | result = wlp_eda_update_node(&wlp->eda, src, wss, | 1733 | result = wlp_eda_update_node(&wlp->eda, src, wss, |
| 1893 | (void *) virt_addr.data, tag, | 1734 | (void *) virt_addr.data, tag, |
| 1894 | WLP_WSS_CONNECTED); | 1735 | WLP_WSS_CONNECTED); |
| @@ -1913,8 +1754,6 @@ void wlp_handle_c3_frame(struct work_struct *ws) | |||
| 1913 | } | 1754 | } |
| 1914 | } | 1755 | } |
| 1915 | } else { | 1756 | } else { |
| 1916 | d_printf(6, dev, "WSSID from C3 frame is not known locally " | ||
| 1917 | "or is not active\n"); | ||
| 1918 | /* Construct F0 frame */ | 1757 | /* Construct F0 frame */ |
| 1919 | result = wlp_build_assoc_f0(wlp, &resp, WLP_ASSOC_ERROR_INV); | 1758 | result = wlp_build_assoc_f0(wlp, &resp, WLP_ASSOC_ERROR_INV); |
| 1920 | if (result < 0) { | 1759 | if (result < 0) { |
| @@ -1923,8 +1762,6 @@ void wlp_handle_c3_frame(struct work_struct *ws) | |||
| 1923 | } | 1762 | } |
| 1924 | } | 1763 | } |
| 1925 | /* Send C4 frame */ | 1764 | /* Send C4 frame */ |
| 1926 | d_printf(6, dev, "Transmitting response (C4/F0) frame to %02x:%02x \n", | ||
| 1927 | src->data[1], src->data[0]); | ||
| 1928 | BUG_ON(wlp->xmit_frame == NULL); | 1765 | BUG_ON(wlp->xmit_frame == NULL); |
| 1929 | result = wlp->xmit_frame(wlp, resp, src); | 1766 | result = wlp->xmit_frame(wlp, resp, src); |
| 1930 | if (result < 0) { | 1767 | if (result < 0) { |
| @@ -1939,8 +1776,6 @@ out: | |||
| 1939 | kfree_skb(frame_ctx->skb); | 1776 | kfree_skb(frame_ctx->skb); |
| 1940 | kfree(frame_ctx); | 1777 | kfree(frame_ctx); |
| 1941 | mutex_unlock(&wss->mutex); | 1778 | mutex_unlock(&wss->mutex); |
| 1942 | d_fnend(6, dev, "WLP: handle C3 frame. wlp = %p, skb = %p\n", | ||
| 1943 | wlp, skb); | ||
| 1944 | } | 1779 | } |
| 1945 | 1780 | ||
| 1946 | 1781 | ||
diff --git a/drivers/uwb/wlp/sysfs.c b/drivers/uwb/wlp/sysfs.c index 1bb9b1f97d4..0370399ff4b 100644 --- a/drivers/uwb/wlp/sysfs.c +++ b/drivers/uwb/wlp/sysfs.c | |||
| @@ -23,8 +23,8 @@ | |||
| 23 | * FIXME: Docs | 23 | * FIXME: Docs |
| 24 | * | 24 | * |
| 25 | */ | 25 | */ |
| 26 | |||
| 27 | #include <linux/wlp.h> | 26 | #include <linux/wlp.h> |
| 27 | |||
| 28 | #include "wlp-internal.h" | 28 | #include "wlp-internal.h" |
| 29 | 29 | ||
| 30 | static | 30 | static |
diff --git a/drivers/uwb/wlp/txrx.c b/drivers/uwb/wlp/txrx.c index c701bd1a288..cd2035768b4 100644 --- a/drivers/uwb/wlp/txrx.c +++ b/drivers/uwb/wlp/txrx.c | |||
| @@ -26,12 +26,10 @@ | |||
| 26 | 26 | ||
| 27 | #include <linux/etherdevice.h> | 27 | #include <linux/etherdevice.h> |
| 28 | #include <linux/wlp.h> | 28 | #include <linux/wlp.h> |
| 29 | #define D_LOCAL 5 | ||
| 30 | #include <linux/uwb/debug.h> | ||
| 31 | #include "wlp-internal.h" | ||
| 32 | 29 | ||
| 30 | #include "wlp-internal.h" | ||
| 33 | 31 | ||
| 34 | /** | 32 | /* |
| 35 | * Direct incoming association msg to correct parsing routine | 33 | * Direct incoming association msg to correct parsing routine |
| 36 | * | 34 | * |
| 37 | * We only expect D1, E1, C1, C3 messages as new. All other incoming | 35 | * We only expect D1, E1, C1, C3 messages as new. All other incoming |
| @@ -48,35 +46,31 @@ void wlp_direct_assoc_frame(struct wlp *wlp, struct sk_buff *skb, | |||
| 48 | struct device *dev = &wlp->rc->uwb_dev.dev; | 46 | struct device *dev = &wlp->rc->uwb_dev.dev; |
| 49 | struct wlp_frame_assoc *assoc = (void *) skb->data; | 47 | struct wlp_frame_assoc *assoc = (void *) skb->data; |
| 50 | struct wlp_assoc_frame_ctx *frame_ctx; | 48 | struct wlp_assoc_frame_ctx *frame_ctx; |
| 51 | d_fnstart(5, dev, "wlp %p, skb %p\n", wlp, skb); | 49 | |
| 52 | frame_ctx = kmalloc(sizeof(*frame_ctx), GFP_ATOMIC); | 50 | frame_ctx = kmalloc(sizeof(*frame_ctx), GFP_ATOMIC); |
| 53 | if (frame_ctx == NULL) { | 51 | if (frame_ctx == NULL) { |
| 54 | dev_err(dev, "WLP: Unable to allocate memory for association " | 52 | dev_err(dev, "WLP: Unable to allocate memory for association " |
| 55 | "frame handling.\n"); | 53 | "frame handling.\n"); |
| 56 | kfree_skb(skb); | 54 | kfree_skb(skb); |
| 57 | goto out; | 55 | return; |
| 58 | } | 56 | } |
| 59 | frame_ctx->wlp = wlp; | 57 | frame_ctx->wlp = wlp; |
| 60 | frame_ctx->skb = skb; | 58 | frame_ctx->skb = skb; |
| 61 | frame_ctx->src = *src; | 59 | frame_ctx->src = *src; |
| 62 | switch (assoc->type) { | 60 | switch (assoc->type) { |
| 63 | case WLP_ASSOC_D1: | 61 | case WLP_ASSOC_D1: |
| 64 | d_printf(5, dev, "Received a D1 frame.\n"); | ||
| 65 | INIT_WORK(&frame_ctx->ws, wlp_handle_d1_frame); | 62 | INIT_WORK(&frame_ctx->ws, wlp_handle_d1_frame); |
| 66 | schedule_work(&frame_ctx->ws); | 63 | schedule_work(&frame_ctx->ws); |
| 67 | break; | 64 | break; |
| 68 | case WLP_ASSOC_E1: | 65 | case WLP_ASSOC_E1: |
| 69 | d_printf(5, dev, "Received a E1 frame. FIXME?\n"); | ||
| 70 | kfree_skb(skb); /* Temporary until we handle it */ | 66 | kfree_skb(skb); /* Temporary until we handle it */ |
| 71 | kfree(frame_ctx); /* Temporary until we handle it */ | 67 | kfree(frame_ctx); /* Temporary until we handle it */ |
| 72 | break; | 68 | break; |
| 73 | case WLP_ASSOC_C1: | 69 | case WLP_ASSOC_C1: |
| 74 | d_printf(5, dev, "Received a C1 frame.\n"); | ||
| 75 | INIT_WORK(&frame_ctx->ws, wlp_handle_c1_frame); | 70 | INIT_WORK(&frame_ctx->ws, wlp_handle_c1_frame); |
| 76 | schedule_work(&frame_ctx->ws); | 71 | schedule_work(&frame_ctx->ws); |
| 77 | break; | 72 | break; |
| 78 | case WLP_ASSOC_C3: | 73 | case WLP_ASSOC_C3: |
| 79 | d_printf(5, dev, "Received a C3 frame.\n"); | ||
| 80 | INIT_WORK(&frame_ctx->ws, wlp_handle_c3_frame); | 74 | INIT_WORK(&frame_ctx->ws, wlp_handle_c3_frame); |
| 81 | schedule_work(&frame_ctx->ws); | 75 | schedule_work(&frame_ctx->ws); |
| 82 | break; | 76 | break; |
| @@ -87,11 +81,9 @@ void wlp_direct_assoc_frame(struct wlp *wlp, struct sk_buff *skb, | |||
| 87 | kfree(frame_ctx); | 81 | kfree(frame_ctx); |
| 88 | break; | 82 | break; |
| 89 | } | 83 | } |
| 90 | out: | ||
| 91 | d_fnend(5, dev, "wlp %p\n", wlp); | ||
| 92 | } | 84 | } |
| 93 | 85 | ||
| 94 | /** | 86 | /* |
| 95 | * Process incoming association frame | 87 | * Process incoming association frame |
| 96 | * | 88 | * |
| 97 | * Although it could be possible to deal with some incoming association | 89 | * Although it could be possible to deal with some incoming association |
| @@ -112,7 +104,6 @@ void wlp_receive_assoc_frame(struct wlp *wlp, struct sk_buff *skb, | |||
| 112 | struct wlp_frame_assoc *assoc = (void *) skb->data; | 104 | struct wlp_frame_assoc *assoc = (void *) skb->data; |
| 113 | struct wlp_session *session = wlp->session; | 105 | struct wlp_session *session = wlp->session; |
| 114 | u8 version; | 106 | u8 version; |
| 115 | d_fnstart(5, dev, "wlp %p, skb %p\n", wlp, skb); | ||
| 116 | 107 | ||
| 117 | if (wlp_get_version(wlp, &assoc->version, &version, | 108 | if (wlp_get_version(wlp, &assoc->version, &version, |
| 118 | sizeof(assoc->version)) < 0) | 109 | sizeof(assoc->version)) < 0) |
| @@ -150,14 +141,12 @@ void wlp_receive_assoc_frame(struct wlp *wlp, struct sk_buff *skb, | |||
| 150 | } else { | 141 | } else { |
| 151 | wlp_direct_assoc_frame(wlp, skb, src); | 142 | wlp_direct_assoc_frame(wlp, skb, src); |
| 152 | } | 143 | } |
| 153 | d_fnend(5, dev, "wlp %p\n", wlp); | ||
| 154 | return; | 144 | return; |
| 155 | error: | 145 | error: |
| 156 | kfree_skb(skb); | 146 | kfree_skb(skb); |
| 157 | d_fnend(5, dev, "wlp %p\n", wlp); | ||
| 158 | } | 147 | } |
| 159 | 148 | ||
| 160 | /** | 149 | /* |
| 161 | * Verify incoming frame is from connected neighbor, prep to pass to WLP client | 150 | * Verify incoming frame is from connected neighbor, prep to pass to WLP client |
| 162 | * | 151 | * |
| 163 | * Verification proceeds according to WLP 0.99 [7.3.1]. The source address | 152 | * Verification proceeds according to WLP 0.99 [7.3.1]. The source address |
| @@ -176,7 +165,6 @@ int wlp_verify_prep_rx_frame(struct wlp *wlp, struct sk_buff *skb, | |||
| 176 | struct wlp_eda_node eda_entry; | 165 | struct wlp_eda_node eda_entry; |
| 177 | struct wlp_frame_std_abbrv_hdr *hdr = (void *) skb->data; | 166 | struct wlp_frame_std_abbrv_hdr *hdr = (void *) skb->data; |
| 178 | 167 | ||
| 179 | d_fnstart(6, dev, "wlp %p, skb %p \n", wlp, skb); | ||
| 180 | /*verify*/ | 168 | /*verify*/ |
| 181 | result = wlp_copy_eda_node(&wlp->eda, src, &eda_entry); | 169 | result = wlp_copy_eda_node(&wlp->eda, src, &eda_entry); |
| 182 | if (result < 0) { | 170 | if (result < 0) { |
| @@ -207,11 +195,10 @@ int wlp_verify_prep_rx_frame(struct wlp *wlp, struct sk_buff *skb, | |||
| 207 | /*prep*/ | 195 | /*prep*/ |
| 208 | skb_pull(skb, sizeof(*hdr)); | 196 | skb_pull(skb, sizeof(*hdr)); |
| 209 | out: | 197 | out: |
| 210 | d_fnend(6, dev, "wlp %p, skb %p, result = %d \n", wlp, skb, result); | ||
| 211 | return result; | 198 | return result; |
| 212 | } | 199 | } |
| 213 | 200 | ||
| 214 | /** | 201 | /* |
| 215 | * Receive a WLP frame from device | 202 | * Receive a WLP frame from device |
| 216 | * | 203 | * |
| 217 | * @returns: 1 if calling function should free the skb | 204 | * @returns: 1 if calling function should free the skb |
| @@ -226,14 +213,12 @@ int wlp_receive_frame(struct device *dev, struct wlp *wlp, struct sk_buff *skb, | |||
| 226 | struct wlp_frame_hdr *hdr; | 213 | struct wlp_frame_hdr *hdr; |
| 227 | int result = 0; | 214 | int result = 0; |
| 228 | 215 | ||
| 229 | d_fnstart(6, dev, "skb (%p), len (%u)\n", skb, len); | ||
| 230 | if (len < sizeof(*hdr)) { | 216 | if (len < sizeof(*hdr)) { |
| 231 | dev_err(dev, "Not enough data to parse WLP header.\n"); | 217 | dev_err(dev, "Not enough data to parse WLP header.\n"); |
| 232 | result = -EINVAL; | 218 | result = -EINVAL; |
| 233 | goto out; | 219 | goto out; |
| 234 | } | 220 | } |
| 235 | hdr = ptr; | 221 | hdr = ptr; |
| 236 | d_dump(6, dev, hdr, sizeof(*hdr)); | ||
| 237 | if (le16_to_cpu(hdr->mux_hdr) != WLP_PROTOCOL_ID) { | 222 | if (le16_to_cpu(hdr->mux_hdr) != WLP_PROTOCOL_ID) { |
| 238 | dev_err(dev, "Not a WLP frame type.\n"); | 223 | dev_err(dev, "Not a WLP frame type.\n"); |
| 239 | result = -EINVAL; | 224 | result = -EINVAL; |
| @@ -270,7 +255,6 @@ int wlp_receive_frame(struct device *dev, struct wlp *wlp, struct sk_buff *skb, | |||
| 270 | "WLP header.\n"); | 255 | "WLP header.\n"); |
| 271 | goto out; | 256 | goto out; |
| 272 | } | 257 | } |
| 273 | d_printf(5, dev, "Association frame received.\n"); | ||
| 274 | wlp_receive_assoc_frame(wlp, skb, src); | 258 | wlp_receive_assoc_frame(wlp, skb, src); |
| 275 | break; | 259 | break; |
| 276 | default: | 260 | default: |
| @@ -283,13 +267,12 @@ out: | |||
| 283 | kfree_skb(skb); | 267 | kfree_skb(skb); |
| 284 | result = 0; | 268 | result = 0; |
| 285 | } | 269 | } |
| 286 | d_fnend(6, dev, "skb (%p)\n", skb); | ||
| 287 | return result; | 270 | return result; |
| 288 | } | 271 | } |
| 289 | EXPORT_SYMBOL_GPL(wlp_receive_frame); | 272 | EXPORT_SYMBOL_GPL(wlp_receive_frame); |
| 290 | 273 | ||
| 291 | 274 | ||
| 292 | /** | 275 | /* |
| 293 | * Verify frame from network stack, prepare for further transmission | 276 | * Verify frame from network stack, prepare for further transmission |
| 294 | * | 277 | * |
| 295 | * @skb: the socket buffer that needs to be prepared for transmission (it | 278 | * @skb: the socket buffer that needs to be prepared for transmission (it |
| @@ -343,9 +326,7 @@ int wlp_prepare_tx_frame(struct device *dev, struct wlp *wlp, | |||
| 343 | int result = -EINVAL; | 326 | int result = -EINVAL; |
| 344 | struct ethhdr *eth_hdr = (void *) skb->data; | 327 | struct ethhdr *eth_hdr = (void *) skb->data; |
| 345 | 328 | ||
| 346 | d_fnstart(6, dev, "wlp (%p), skb (%p) \n", wlp, skb); | ||
| 347 | if (is_broadcast_ether_addr(eth_hdr->h_dest)) { | 329 | if (is_broadcast_ether_addr(eth_hdr->h_dest)) { |
| 348 | d_printf(6, dev, "WLP: handling broadcast frame. \n"); | ||
| 349 | result = wlp_eda_for_each(&wlp->eda, wlp_wss_send_copy, skb); | 330 | result = wlp_eda_for_each(&wlp->eda, wlp_wss_send_copy, skb); |
| 350 | if (result < 0) { | 331 | if (result < 0) { |
| 351 | if (printk_ratelimit()) | 332 | if (printk_ratelimit()) |
| @@ -357,7 +338,6 @@ int wlp_prepare_tx_frame(struct device *dev, struct wlp *wlp, | |||
| 357 | result = 1; | 338 | result = 1; |
| 358 | /* Frame will be transmitted by WLP. */ | 339 | /* Frame will be transmitted by WLP. */ |
| 359 | } else { | 340 | } else { |
| 360 | d_printf(6, dev, "WLP: handling unicast frame. \n"); | ||
| 361 | result = wlp_eda_for_virtual(&wlp->eda, eth_hdr->h_dest, dst, | 341 | result = wlp_eda_for_virtual(&wlp->eda, eth_hdr->h_dest, dst, |
| 362 | wlp_wss_prep_hdr, skb); | 342 | wlp_wss_prep_hdr, skb); |
| 363 | if (unlikely(result < 0)) { | 343 | if (unlikely(result < 0)) { |
| @@ -368,7 +348,6 @@ int wlp_prepare_tx_frame(struct device *dev, struct wlp *wlp, | |||
| 368 | } | 348 | } |
| 369 | } | 349 | } |
| 370 | out: | 350 | out: |
| 371 | d_fnend(6, dev, "wlp (%p), skb (%p). result = %d \n", wlp, skb, result); | ||
| 372 | return result; | 351 | return result; |
| 373 | } | 352 | } |
| 374 | EXPORT_SYMBOL_GPL(wlp_prepare_tx_frame); | 353 | EXPORT_SYMBOL_GPL(wlp_prepare_tx_frame); |
diff --git a/drivers/uwb/wlp/wlp-internal.h b/drivers/uwb/wlp/wlp-internal.h index 1c94fabfb1a..3e8d5de7c5b 100644 --- a/drivers/uwb/wlp/wlp-internal.h +++ b/drivers/uwb/wlp/wlp-internal.h | |||
| @@ -42,10 +42,6 @@ enum wlp_wss_connect { | |||
| 42 | extern struct kobj_type wss_ktype; | 42 | extern struct kobj_type wss_ktype; |
| 43 | extern struct attribute_group wss_attr_group; | 43 | extern struct attribute_group wss_attr_group; |
| 44 | 44 | ||
| 45 | extern int uwb_rc_ie_add(struct uwb_rc *, const struct uwb_ie_hdr *, size_t); | ||
| 46 | extern int uwb_rc_ie_rm(struct uwb_rc *, enum uwb_ie); | ||
| 47 | |||
| 48 | |||
| 49 | /* This should be changed to a dynamic array where entries are sorted | 45 | /* This should be changed to a dynamic array where entries are sorted |
| 50 | * by eth_addr and search is done in a binary form | 46 | * by eth_addr and search is done in a binary form |
| 51 | * | 47 | * |
diff --git a/drivers/uwb/wlp/wlp-lc.c b/drivers/uwb/wlp/wlp-lc.c index 0799402e73f..13db739c4e3 100644 --- a/drivers/uwb/wlp/wlp-lc.c +++ b/drivers/uwb/wlp/wlp-lc.c | |||
| @@ -21,12 +21,9 @@ | |||
| 21 | * | 21 | * |
| 22 | * FIXME: docs | 22 | * FIXME: docs |
| 23 | */ | 23 | */ |
| 24 | |||
| 25 | #include <linux/wlp.h> | 24 | #include <linux/wlp.h> |
| 26 | #define D_LOCAL 6 | ||
| 27 | #include <linux/uwb/debug.h> | ||
| 28 | #include "wlp-internal.h" | ||
| 29 | 25 | ||
| 26 | #include "wlp-internal.h" | ||
| 30 | 27 | ||
| 31 | static | 28 | static |
| 32 | void wlp_neighbor_init(struct wlp_neighbor_e *neighbor) | 29 | void wlp_neighbor_init(struct wlp_neighbor_e *neighbor) |
| @@ -61,11 +58,6 @@ int __wlp_alloc_device_info(struct wlp *wlp) | |||
| 61 | static | 58 | static |
| 62 | void __wlp_fill_device_info(struct wlp *wlp) | 59 | void __wlp_fill_device_info(struct wlp *wlp) |
| 63 | { | 60 | { |
| 64 | struct device *dev = &wlp->rc->uwb_dev.dev; | ||
| 65 | |||
| 66 | BUG_ON(wlp->fill_device_info == NULL); | ||
| 67 | d_printf(6, dev, "Retrieving device information " | ||
| 68 | "from device driver.\n"); | ||
| 69 | wlp->fill_device_info(wlp, wlp->dev_info); | 61 | wlp->fill_device_info(wlp, wlp->dev_info); |
| 70 | } | 62 | } |
| 71 | 63 | ||
| @@ -127,7 +119,7 @@ void wlp_remove_neighbor_tmp_info(struct wlp_neighbor_e *neighbor) | |||
| 127 | } | 119 | } |
| 128 | } | 120 | } |
| 129 | 121 | ||
| 130 | /** | 122 | /* |
| 131 | * Populate WLP neighborhood cache with neighbor information | 123 | * Populate WLP neighborhood cache with neighbor information |
| 132 | * | 124 | * |
| 133 | * A new neighbor is found. If it is discoverable then we add it to the | 125 | * A new neighbor is found. If it is discoverable then we add it to the |
| @@ -141,10 +133,7 @@ int wlp_add_neighbor(struct wlp *wlp, struct uwb_dev *dev) | |||
| 141 | int discoverable; | 133 | int discoverable; |
| 142 | struct wlp_neighbor_e *neighbor; | 134 | struct wlp_neighbor_e *neighbor; |
| 143 | 135 | ||
| 144 | d_fnstart(6, &dev->dev, "uwb %p \n", dev); | 136 | /* |
| 145 | d_printf(6, &dev->dev, "Found neighbor device %02x:%02x \n", | ||
| 146 | dev->dev_addr.data[1], dev->dev_addr.data[0]); | ||
| 147 | /** | ||
| 148 | * FIXME: | 137 | * FIXME: |
| 149 | * Use contents of WLP IE found in beacon cache to determine if | 138 | * Use contents of WLP IE found in beacon cache to determine if |
| 150 | * neighbor is discoverable. | 139 | * neighbor is discoverable. |
| @@ -167,7 +156,6 @@ int wlp_add_neighbor(struct wlp *wlp, struct uwb_dev *dev) | |||
| 167 | list_add(&neighbor->node, &wlp->neighbors); | 156 | list_add(&neighbor->node, &wlp->neighbors); |
| 168 | } | 157 | } |
| 169 | error_no_mem: | 158 | error_no_mem: |
| 170 | d_fnend(6, &dev->dev, "uwb %p, result = %d \n", dev, result); | ||
| 171 | return result; | 159 | return result; |
| 172 | } | 160 | } |
| 173 | 161 | ||
| @@ -255,8 +243,6 @@ int wlp_d1d2_exchange(struct wlp *wlp, struct wlp_neighbor_e *neighbor, | |||
| 255 | dev_err(dev, "Unable to send D1 frame to neighbor " | 243 | dev_err(dev, "Unable to send D1 frame to neighbor " |
| 256 | "%02x:%02x (%d)\n", dev_addr->data[1], | 244 | "%02x:%02x (%d)\n", dev_addr->data[1], |
| 257 | dev_addr->data[0], result); | 245 | dev_addr->data[0], result); |
| 258 | d_printf(6, dev, "Add placeholders into buffer next to " | ||
| 259 | "neighbor information we have (dev address).\n"); | ||
| 260 | goto out; | 246 | goto out; |
| 261 | } | 247 | } |
| 262 | /* Create session, wait for response */ | 248 | /* Create session, wait for response */ |
| @@ -284,8 +270,6 @@ int wlp_d1d2_exchange(struct wlp *wlp, struct wlp_neighbor_e *neighbor, | |||
| 284 | /* Parse message in session->data: it will be either D2 or F0 */ | 270 | /* Parse message in session->data: it will be either D2 or F0 */ |
| 285 | skb = session.data; | 271 | skb = session.data; |
| 286 | resp = (void *) skb->data; | 272 | resp = (void *) skb->data; |
| 287 | d_printf(6, dev, "Received response to D1 frame. \n"); | ||
| 288 | d_dump(6, dev, skb->data, skb->len > 72 ? 72 : skb->len); | ||
| 289 | 273 | ||
| 290 | if (resp->type == WLP_ASSOC_F0) { | 274 | if (resp->type == WLP_ASSOC_F0) { |
| 291 | result = wlp_parse_f0(wlp, skb); | 275 | result = wlp_parse_f0(wlp, skb); |
| @@ -337,10 +321,9 @@ int wlp_enroll_neighbor(struct wlp *wlp, struct wlp_neighbor_e *neighbor, | |||
| 337 | struct device *dev = &wlp->rc->uwb_dev.dev; | 321 | struct device *dev = &wlp->rc->uwb_dev.dev; |
| 338 | char buf[WLP_WSS_UUID_STRSIZE]; | 322 | char buf[WLP_WSS_UUID_STRSIZE]; |
| 339 | struct uwb_dev_addr *dev_addr = &neighbor->uwb_dev->dev_addr; | 323 | struct uwb_dev_addr *dev_addr = &neighbor->uwb_dev->dev_addr; |
| 324 | |||
| 340 | wlp_wss_uuid_print(buf, sizeof(buf), wssid); | 325 | wlp_wss_uuid_print(buf, sizeof(buf), wssid); |
| 341 | d_fnstart(6, dev, "wlp %p, neighbor %p, wss %p, wssid %p (%s)\n", | 326 | |
| 342 | wlp, neighbor, wss, wssid, buf); | ||
| 343 | d_printf(6, dev, "Complete me.\n"); | ||
| 344 | result = wlp_d1d2_exchange(wlp, neighbor, wss, wssid); | 327 | result = wlp_d1d2_exchange(wlp, neighbor, wss, wssid); |
| 345 | if (result < 0) { | 328 | if (result < 0) { |
| 346 | dev_err(dev, "WLP: D1/D2 message exchange for enrollment " | 329 | dev_err(dev, "WLP: D1/D2 message exchange for enrollment " |
| @@ -360,13 +343,10 @@ int wlp_enroll_neighbor(struct wlp *wlp, struct wlp_neighbor_e *neighbor, | |||
| 360 | goto error; | 343 | goto error; |
| 361 | } else { | 344 | } else { |
| 362 | wss->state = WLP_WSS_STATE_ENROLLED; | 345 | wss->state = WLP_WSS_STATE_ENROLLED; |
| 363 | d_printf(2, dev, "WLP: Success Enrollment into unsecure WSS " | 346 | dev_dbg(dev, "WLP: Success Enrollment into unsecure WSS " |
| 364 | "%s using neighbor %02x:%02x. \n", buf, | 347 | "%s using neighbor %02x:%02x. \n", |
| 365 | dev_addr->data[1], dev_addr->data[0]); | 348 | buf, dev_addr->data[1], dev_addr->data[0]); |
| 366 | } | 349 | } |
| 367 | |||
| 368 | d_fnend(6, dev, "wlp %p, neighbor %p, wss %p, wssid %p (%s)\n", | ||
| 369 | wlp, neighbor, wss, wssid, buf); | ||
| 370 | out: | 350 | out: |
| 371 | return result; | 351 | return result; |
| 372 | error: | 352 | error: |
| @@ -449,7 +429,6 @@ ssize_t wlp_discover(struct wlp *wlp) | |||
| 449 | int result = 0; | 429 | int result = 0; |
| 450 | struct device *dev = &wlp->rc->uwb_dev.dev; | 430 | struct device *dev = &wlp->rc->uwb_dev.dev; |
| 451 | 431 | ||
| 452 | d_fnstart(6, dev, "wlp %p \n", wlp); | ||
| 453 | mutex_lock(&wlp->nbmutex); | 432 | mutex_lock(&wlp->nbmutex); |
| 454 | /* Clear current neighborhood cache. */ | 433 | /* Clear current neighborhood cache. */ |
| 455 | __wlp_neighbors_release(wlp); | 434 | __wlp_neighbors_release(wlp); |
| @@ -469,7 +448,6 @@ ssize_t wlp_discover(struct wlp *wlp) | |||
| 469 | } | 448 | } |
| 470 | error_dev_for_each: | 449 | error_dev_for_each: |
| 471 | mutex_unlock(&wlp->nbmutex); | 450 | mutex_unlock(&wlp->nbmutex); |
| 472 | d_fnend(6, dev, "wlp %p \n", wlp); | ||
| 473 | return result; | 451 | return result; |
| 474 | } | 452 | } |
| 475 | 453 | ||
| @@ -492,9 +470,6 @@ void wlp_uwb_notifs_cb(void *_wlp, struct uwb_dev *uwb_dev, | |||
| 492 | int result; | 470 | int result; |
| 493 | switch (event) { | 471 | switch (event) { |
| 494 | case UWB_NOTIF_ONAIR: | 472 | case UWB_NOTIF_ONAIR: |
| 495 | d_printf(6, dev, "UWB device %02x:%02x is onair\n", | ||
| 496 | uwb_dev->dev_addr.data[1], | ||
| 497 | uwb_dev->dev_addr.data[0]); | ||
| 498 | result = wlp_eda_create_node(&wlp->eda, | 473 | result = wlp_eda_create_node(&wlp->eda, |
| 499 | uwb_dev->mac_addr.data, | 474 | uwb_dev->mac_addr.data, |
| 500 | &uwb_dev->dev_addr); | 475 | &uwb_dev->dev_addr); |
| @@ -505,18 +480,11 @@ void wlp_uwb_notifs_cb(void *_wlp, struct uwb_dev *uwb_dev, | |||
| 505 | uwb_dev->dev_addr.data[0]); | 480 | uwb_dev->dev_addr.data[0]); |
| 506 | break; | 481 | break; |
| 507 | case UWB_NOTIF_OFFAIR: | 482 | case UWB_NOTIF_OFFAIR: |
| 508 | d_printf(6, dev, "UWB device %02x:%02x is offair\n", | ||
| 509 | uwb_dev->dev_addr.data[1], | ||
| 510 | uwb_dev->dev_addr.data[0]); | ||
| 511 | wlp_eda_rm_node(&wlp->eda, &uwb_dev->dev_addr); | 483 | wlp_eda_rm_node(&wlp->eda, &uwb_dev->dev_addr); |
| 512 | mutex_lock(&wlp->nbmutex); | 484 | mutex_lock(&wlp->nbmutex); |
| 513 | list_for_each_entry_safe(neighbor, next, &wlp->neighbors, | 485 | list_for_each_entry_safe(neighbor, next, &wlp->neighbors, node) { |
| 514 | node) { | 486 | if (neighbor->uwb_dev == uwb_dev) |
| 515 | if (neighbor->uwb_dev == uwb_dev) { | ||
| 516 | d_printf(6, dev, "Removing device from " | ||
| 517 | "neighborhood.\n"); | ||
| 518 | __wlp_neighbor_release(neighbor); | 487 | __wlp_neighbor_release(neighbor); |
| 519 | } | ||
| 520 | } | 488 | } |
| 521 | mutex_unlock(&wlp->nbmutex); | 489 | mutex_unlock(&wlp->nbmutex); |
| 522 | break; | 490 | break; |
| @@ -526,38 +494,47 @@ void wlp_uwb_notifs_cb(void *_wlp, struct uwb_dev *uwb_dev, | |||
| 526 | } | 494 | } |
| 527 | } | 495 | } |
| 528 | 496 | ||
| 529 | int wlp_setup(struct wlp *wlp, struct uwb_rc *rc) | 497 | static void wlp_channel_changed(struct uwb_pal *pal, int channel) |
| 498 | { | ||
| 499 | struct wlp *wlp = container_of(pal, struct wlp, pal); | ||
| 500 | |||
| 501 | if (channel < 0) | ||
| 502 | netif_carrier_off(wlp->ndev); | ||
| 503 | else | ||
| 504 | netif_carrier_on(wlp->ndev); | ||
| 505 | } | ||
| 506 | |||
| 507 | int wlp_setup(struct wlp *wlp, struct uwb_rc *rc, struct net_device *ndev) | ||
| 530 | { | 508 | { |
| 531 | struct device *dev = &rc->uwb_dev.dev; | ||
| 532 | int result; | 509 | int result; |
| 533 | 510 | ||
| 534 | d_fnstart(6, dev, "wlp %p\n", wlp); | ||
| 535 | BUG_ON(wlp->fill_device_info == NULL); | 511 | BUG_ON(wlp->fill_device_info == NULL); |
| 536 | BUG_ON(wlp->xmit_frame == NULL); | 512 | BUG_ON(wlp->xmit_frame == NULL); |
| 537 | BUG_ON(wlp->stop_queue == NULL); | 513 | BUG_ON(wlp->stop_queue == NULL); |
| 538 | BUG_ON(wlp->start_queue == NULL); | 514 | BUG_ON(wlp->start_queue == NULL); |
| 515 | |||
| 539 | wlp->rc = rc; | 516 | wlp->rc = rc; |
| 517 | wlp->ndev = ndev; | ||
| 540 | wlp_eda_init(&wlp->eda);/* Set up address cache */ | 518 | wlp_eda_init(&wlp->eda);/* Set up address cache */ |
| 541 | wlp->uwb_notifs_handler.cb = wlp_uwb_notifs_cb; | 519 | wlp->uwb_notifs_handler.cb = wlp_uwb_notifs_cb; |
| 542 | wlp->uwb_notifs_handler.data = wlp; | 520 | wlp->uwb_notifs_handler.data = wlp; |
| 543 | uwb_notifs_register(rc, &wlp->uwb_notifs_handler); | 521 | uwb_notifs_register(rc, &wlp->uwb_notifs_handler); |
| 544 | 522 | ||
| 545 | uwb_pal_init(&wlp->pal); | 523 | uwb_pal_init(&wlp->pal); |
| 546 | result = uwb_pal_register(rc, &wlp->pal); | 524 | wlp->pal.rc = rc; |
| 525 | wlp->pal.channel_changed = wlp_channel_changed; | ||
| 526 | result = uwb_pal_register(&wlp->pal); | ||
| 547 | if (result < 0) | 527 | if (result < 0) |
| 548 | uwb_notifs_deregister(wlp->rc, &wlp->uwb_notifs_handler); | 528 | uwb_notifs_deregister(wlp->rc, &wlp->uwb_notifs_handler); |
| 549 | 529 | ||
| 550 | d_fnend(6, dev, "wlp %p, result = %d\n", wlp, result); | ||
| 551 | return result; | 530 | return result; |
| 552 | } | 531 | } |
| 553 | EXPORT_SYMBOL_GPL(wlp_setup); | 532 | EXPORT_SYMBOL_GPL(wlp_setup); |
| 554 | 533 | ||
| 555 | void wlp_remove(struct wlp *wlp) | 534 | void wlp_remove(struct wlp *wlp) |
| 556 | { | 535 | { |
| 557 | struct device *dev = &wlp->rc->uwb_dev.dev; | ||
| 558 | d_fnstart(6, dev, "wlp %p\n", wlp); | ||
| 559 | wlp_neighbors_release(wlp); | 536 | wlp_neighbors_release(wlp); |
| 560 | uwb_pal_unregister(wlp->rc, &wlp->pal); | 537 | uwb_pal_unregister(&wlp->pal); |
| 561 | uwb_notifs_deregister(wlp->rc, &wlp->uwb_notifs_handler); | 538 | uwb_notifs_deregister(wlp->rc, &wlp->uwb_notifs_handler); |
| 562 | wlp_eda_release(&wlp->eda); | 539 | wlp_eda_release(&wlp->eda); |
| 563 | mutex_lock(&wlp->mutex); | 540 | mutex_lock(&wlp->mutex); |
| @@ -565,9 +542,6 @@ void wlp_remove(struct wlp *wlp) | |||
| 565 | kfree(wlp->dev_info); | 542 | kfree(wlp->dev_info); |
| 566 | mutex_unlock(&wlp->mutex); | 543 | mutex_unlock(&wlp->mutex); |
| 567 | wlp->rc = NULL; | 544 | wlp->rc = NULL; |
| 568 | /* We have to use NULL here because this function can be called | ||
| 569 | * when the device disappeared. */ | ||
| 570 | d_fnend(6, NULL, "wlp %p\n", wlp); | ||
| 571 | } | 545 | } |
| 572 | EXPORT_SYMBOL_GPL(wlp_remove); | 546 | EXPORT_SYMBOL_GPL(wlp_remove); |
| 573 | 547 | ||
diff --git a/drivers/uwb/wlp/wss-lc.c b/drivers/uwb/wlp/wss-lc.c index 96b18c9bd6e..5913c7a5d92 100644 --- a/drivers/uwb/wlp/wss-lc.c +++ b/drivers/uwb/wlp/wss-lc.c | |||
| @@ -43,14 +43,11 @@ | |||
| 43 | * wlp_wss_release() | 43 | * wlp_wss_release() |
| 44 | * wlp_wss_reset() | 44 | * wlp_wss_reset() |
| 45 | */ | 45 | */ |
| 46 | |||
| 47 | #include <linux/etherdevice.h> /* for is_valid_ether_addr */ | 46 | #include <linux/etherdevice.h> /* for is_valid_ether_addr */ |
| 48 | #include <linux/skbuff.h> | 47 | #include <linux/skbuff.h> |
| 49 | #include <linux/wlp.h> | 48 | #include <linux/wlp.h> |
| 50 | #define D_LOCAL 5 | ||
| 51 | #include <linux/uwb/debug.h> | ||
| 52 | #include "wlp-internal.h" | ||
| 53 | 49 | ||
| 50 | #include "wlp-internal.h" | ||
| 54 | 51 | ||
| 55 | size_t wlp_wss_key_print(char *buf, size_t bufsize, u8 *key) | 52 | size_t wlp_wss_key_print(char *buf, size_t bufsize, u8 *key) |
| 56 | { | 53 | { |
| @@ -116,9 +113,6 @@ struct uwb_mac_addr wlp_wss_sel_bcast_addr(struct wlp_wss *wss) | |||
| 116 | */ | 113 | */ |
| 117 | void wlp_wss_reset(struct wlp_wss *wss) | 114 | void wlp_wss_reset(struct wlp_wss *wss) |
| 118 | { | 115 | { |
| 119 | struct wlp *wlp = container_of(wss, struct wlp, wss); | ||
| 120 | struct device *dev = &wlp->rc->uwb_dev.dev; | ||
| 121 | d_fnstart(5, dev, "wss (%p) \n", wss); | ||
| 122 | memset(&wss->wssid, 0, sizeof(wss->wssid)); | 116 | memset(&wss->wssid, 0, sizeof(wss->wssid)); |
| 123 | wss->hash = 0; | 117 | wss->hash = 0; |
| 124 | memset(&wss->name[0], 0, sizeof(wss->name)); | 118 | memset(&wss->name[0], 0, sizeof(wss->name)); |
| @@ -127,7 +121,6 @@ void wlp_wss_reset(struct wlp_wss *wss) | |||
| 127 | memset(&wss->master_key[0], 0, sizeof(wss->master_key)); | 121 | memset(&wss->master_key[0], 0, sizeof(wss->master_key)); |
| 128 | wss->tag = 0; | 122 | wss->tag = 0; |
| 129 | wss->state = WLP_WSS_STATE_NONE; | 123 | wss->state = WLP_WSS_STATE_NONE; |
| 130 | d_fnend(5, dev, "wss (%p) \n", wss); | ||
| 131 | } | 124 | } |
| 132 | 125 | ||
| 133 | /** | 126 | /** |
| @@ -145,7 +138,6 @@ int wlp_wss_sysfs_add(struct wlp_wss *wss, char *wssid_str) | |||
| 145 | struct device *dev = &wlp->rc->uwb_dev.dev; | 138 | struct device *dev = &wlp->rc->uwb_dev.dev; |
| 146 | int result; | 139 | int result; |
| 147 | 140 | ||
| 148 | d_fnstart(5, dev, "wss (%p), wssid: %s\n", wss, wssid_str); | ||
| 149 | result = kobject_set_name(&wss->kobj, "wss-%s", wssid_str); | 141 | result = kobject_set_name(&wss->kobj, "wss-%s", wssid_str); |
| 150 | if (result < 0) | 142 | if (result < 0) |
| 151 | return result; | 143 | return result; |
| @@ -162,7 +154,6 @@ int wlp_wss_sysfs_add(struct wlp_wss *wss, char *wssid_str) | |||
| 162 | result); | 154 | result); |
| 163 | goto error_sysfs_create_group; | 155 | goto error_sysfs_create_group; |
| 164 | } | 156 | } |
| 165 | d_fnend(5, dev, "Completed. result = %d \n", result); | ||
| 166 | return 0; | 157 | return 0; |
| 167 | error_sysfs_create_group: | 158 | error_sysfs_create_group: |
| 168 | 159 | ||
| @@ -214,22 +205,14 @@ int wlp_wss_enroll_target(struct wlp_wss *wss, struct wlp_uuid *wssid, | |||
| 214 | struct wlp *wlp = container_of(wss, struct wlp, wss); | 205 | struct wlp *wlp = container_of(wss, struct wlp, wss); |
| 215 | struct device *dev = &wlp->rc->uwb_dev.dev; | 206 | struct device *dev = &wlp->rc->uwb_dev.dev; |
| 216 | struct wlp_neighbor_e *neighbor; | 207 | struct wlp_neighbor_e *neighbor; |
| 217 | char buf[WLP_WSS_UUID_STRSIZE]; | ||
| 218 | int result = -ENXIO; | 208 | int result = -ENXIO; |
| 219 | struct uwb_dev_addr *dev_addr; | 209 | struct uwb_dev_addr *dev_addr; |
| 220 | 210 | ||
| 221 | wlp_wss_uuid_print(buf, sizeof(buf), wssid); | ||
| 222 | d_fnstart(5, dev, "wss %p, wssid %s, registrar %02x:%02x \n", | ||
| 223 | wss, buf, dest->data[1], dest->data[0]); | ||
| 224 | mutex_lock(&wlp->nbmutex); | 211 | mutex_lock(&wlp->nbmutex); |
| 225 | list_for_each_entry(neighbor, &wlp->neighbors, node) { | 212 | list_for_each_entry(neighbor, &wlp->neighbors, node) { |
| 226 | dev_addr = &neighbor->uwb_dev->dev_addr; | 213 | dev_addr = &neighbor->uwb_dev->dev_addr; |
| 227 | if (!memcmp(dest, dev_addr, sizeof(*dest))) { | 214 | if (!memcmp(dest, dev_addr, sizeof(*dest))) { |
| 228 | d_printf(5, dev, "Neighbor %02x:%02x is valid, " | 215 | result = wlp_enroll_neighbor(wlp, neighbor, wss, wssid); |
| 229 | "enrolling. \n", | ||
| 230 | dev_addr->data[1], dev_addr->data[0]); | ||
| 231 | result = wlp_enroll_neighbor(wlp, neighbor, wss, | ||
| 232 | wssid); | ||
| 233 | break; | 216 | break; |
| 234 | } | 217 | } |
| 235 | } | 218 | } |
| @@ -237,8 +220,6 @@ int wlp_wss_enroll_target(struct wlp_wss *wss, struct wlp_uuid *wssid, | |||
| 237 | dev_err(dev, "WLP: Cannot find neighbor %02x:%02x. \n", | 220 | dev_err(dev, "WLP: Cannot find neighbor %02x:%02x. \n", |
| 238 | dest->data[1], dest->data[0]); | 221 | dest->data[1], dest->data[0]); |
| 239 | mutex_unlock(&wlp->nbmutex); | 222 | mutex_unlock(&wlp->nbmutex); |
| 240 | d_fnend(5, dev, "wss %p, wssid %s, registrar %02x:%02x, result %d \n", | ||
| 241 | wss, buf, dest->data[1], dest->data[0], result); | ||
| 242 | return result; | 223 | return result; |
| 243 | } | 224 | } |
| 244 | 225 | ||
| @@ -260,16 +241,11 @@ int wlp_wss_enroll_discovered(struct wlp_wss *wss, struct wlp_uuid *wssid) | |||
| 260 | char buf[WLP_WSS_UUID_STRSIZE]; | 241 | char buf[WLP_WSS_UUID_STRSIZE]; |
| 261 | int result = -ENXIO; | 242 | int result = -ENXIO; |
| 262 | 243 | ||
| 263 | wlp_wss_uuid_print(buf, sizeof(buf), wssid); | 244 | |
| 264 | d_fnstart(5, dev, "wss %p, wssid %s \n", wss, buf); | ||
| 265 | mutex_lock(&wlp->nbmutex); | 245 | mutex_lock(&wlp->nbmutex); |
| 266 | list_for_each_entry(neighbor, &wlp->neighbors, node) { | 246 | list_for_each_entry(neighbor, &wlp->neighbors, node) { |
| 267 | list_for_each_entry(wssid_e, &neighbor->wssid, node) { | 247 | list_for_each_entry(wssid_e, &neighbor->wssid, node) { |
| 268 | if (!memcmp(wssid, &wssid_e->wssid, sizeof(*wssid))) { | 248 | if (!memcmp(wssid, &wssid_e->wssid, sizeof(*wssid))) { |
| 269 | d_printf(5, dev, "Found WSSID %s in neighbor " | ||
| 270 | "%02x:%02x cache. \n", buf, | ||
| 271 | neighbor->uwb_dev->dev_addr.data[1], | ||
| 272 | neighbor->uwb_dev->dev_addr.data[0]); | ||
| 273 | result = wlp_enroll_neighbor(wlp, neighbor, | 249 | result = wlp_enroll_neighbor(wlp, neighbor, |
| 274 | wss, wssid); | 250 | wss, wssid); |
| 275 | if (result == 0) /* enrollment success */ | 251 | if (result == 0) /* enrollment success */ |
| @@ -279,10 +255,11 @@ int wlp_wss_enroll_discovered(struct wlp_wss *wss, struct wlp_uuid *wssid) | |||
| 279 | } | 255 | } |
| 280 | } | 256 | } |
| 281 | out: | 257 | out: |
| 282 | if (result == -ENXIO) | 258 | if (result == -ENXIO) { |
| 259 | wlp_wss_uuid_print(buf, sizeof(buf), wssid); | ||
| 283 | dev_err(dev, "WLP: Cannot find WSSID %s in cache. \n", buf); | 260 | dev_err(dev, "WLP: Cannot find WSSID %s in cache. \n", buf); |
| 261 | } | ||
| 284 | mutex_unlock(&wlp->nbmutex); | 262 | mutex_unlock(&wlp->nbmutex); |
| 285 | d_fnend(5, dev, "wss %p, wssid %s, result %d \n", wss, buf, result); | ||
| 286 | return result; | 263 | return result; |
| 287 | } | 264 | } |
| 288 | 265 | ||
| @@ -307,27 +284,22 @@ int wlp_wss_enroll(struct wlp_wss *wss, struct wlp_uuid *wssid, | |||
| 307 | struct uwb_dev_addr bcast = {.data = {0xff, 0xff} }; | 284 | struct uwb_dev_addr bcast = {.data = {0xff, 0xff} }; |
| 308 | 285 | ||
| 309 | wlp_wss_uuid_print(buf, sizeof(buf), wssid); | 286 | wlp_wss_uuid_print(buf, sizeof(buf), wssid); |
| 287 | |||
| 310 | if (wss->state != WLP_WSS_STATE_NONE) { | 288 | if (wss->state != WLP_WSS_STATE_NONE) { |
| 311 | dev_err(dev, "WLP: Already enrolled in WSS %s.\n", buf); | 289 | dev_err(dev, "WLP: Already enrolled in WSS %s.\n", buf); |
| 312 | result = -EEXIST; | 290 | result = -EEXIST; |
| 313 | goto error; | 291 | goto error; |
| 314 | } | 292 | } |
| 315 | if (!memcmp(&bcast, devaddr, sizeof(bcast))) { | 293 | if (!memcmp(&bcast, devaddr, sizeof(bcast))) |
| 316 | d_printf(5, dev, "Request to enroll in discovered WSS " | ||
| 317 | "with WSSID %s \n", buf); | ||
| 318 | result = wlp_wss_enroll_discovered(wss, wssid); | 294 | result = wlp_wss_enroll_discovered(wss, wssid); |
| 319 | } else { | 295 | else |
| 320 | d_printf(5, dev, "Request to enroll in WSSID %s with " | ||
| 321 | "registrar %02x:%02x\n", buf, devaddr->data[1], | ||
| 322 | devaddr->data[0]); | ||
| 323 | result = wlp_wss_enroll_target(wss, wssid, devaddr); | 296 | result = wlp_wss_enroll_target(wss, wssid, devaddr); |
| 324 | } | ||
| 325 | if (result < 0) { | 297 | if (result < 0) { |
| 326 | dev_err(dev, "WLP: Unable to enroll into WSS %s, result %d \n", | 298 | dev_err(dev, "WLP: Unable to enroll into WSS %s, result %d \n", |
| 327 | buf, result); | 299 | buf, result); |
| 328 | goto error; | 300 | goto error; |
| 329 | } | 301 | } |
| 330 | d_printf(2, dev, "Successfully enrolled into WSS %s \n", buf); | 302 | dev_dbg(dev, "Successfully enrolled into WSS %s \n", buf); |
| 331 | result = wlp_wss_sysfs_add(wss, buf); | 303 | result = wlp_wss_sysfs_add(wss, buf); |
| 332 | if (result < 0) { | 304 | if (result < 0) { |
| 333 | dev_err(dev, "WLP: Unable to set up sysfs for WSS kobject.\n"); | 305 | dev_err(dev, "WLP: Unable to set up sysfs for WSS kobject.\n"); |
| @@ -363,7 +335,6 @@ int wlp_wss_activate(struct wlp_wss *wss) | |||
| 363 | u8 hash; /* only include one hash */ | 335 | u8 hash; /* only include one hash */ |
| 364 | } ie_data; | 336 | } ie_data; |
| 365 | 337 | ||
| 366 | d_fnstart(5, dev, "Activating WSS %p. \n", wss); | ||
| 367 | BUG_ON(wss->state != WLP_WSS_STATE_ENROLLED); | 338 | BUG_ON(wss->state != WLP_WSS_STATE_ENROLLED); |
| 368 | wss->hash = wlp_wss_comp_wssid_hash(&wss->wssid); | 339 | wss->hash = wlp_wss_comp_wssid_hash(&wss->wssid); |
| 369 | wss->tag = wss->hash; | 340 | wss->tag = wss->hash; |
| @@ -382,7 +353,6 @@ int wlp_wss_activate(struct wlp_wss *wss) | |||
| 382 | wss->state = WLP_WSS_STATE_ACTIVE; | 353 | wss->state = WLP_WSS_STATE_ACTIVE; |
| 383 | result = 0; | 354 | result = 0; |
| 384 | error_wlp_ie: | 355 | error_wlp_ie: |
| 385 | d_fnend(5, dev, "Activating WSS %p, result = %d \n", wss, result); | ||
| 386 | return result; | 356 | return result; |
| 387 | } | 357 | } |
| 388 | 358 | ||
| @@ -405,7 +375,6 @@ int wlp_wss_enroll_activate(struct wlp_wss *wss, struct wlp_uuid *wssid, | |||
| 405 | int result = 0; | 375 | int result = 0; |
| 406 | char buf[WLP_WSS_UUID_STRSIZE]; | 376 | char buf[WLP_WSS_UUID_STRSIZE]; |
| 407 | 377 | ||
| 408 | d_fnstart(5, dev, "Enrollment and activation requested. \n"); | ||
| 409 | mutex_lock(&wss->mutex); | 378 | mutex_lock(&wss->mutex); |
| 410 | result = wlp_wss_enroll(wss, wssid, devaddr); | 379 | result = wlp_wss_enroll(wss, wssid, devaddr); |
| 411 | if (result < 0) { | 380 | if (result < 0) { |
| @@ -424,7 +393,6 @@ int wlp_wss_enroll_activate(struct wlp_wss *wss, struct wlp_uuid *wssid, | |||
| 424 | error_activate: | 393 | error_activate: |
| 425 | error_enroll: | 394 | error_enroll: |
| 426 | mutex_unlock(&wss->mutex); | 395 | mutex_unlock(&wss->mutex); |
| 427 | d_fnend(5, dev, "Completed. result = %d \n", result); | ||
| 428 | return result; | 396 | return result; |
| 429 | } | 397 | } |
| 430 | 398 | ||
| @@ -447,11 +415,9 @@ int wlp_wss_create_activate(struct wlp_wss *wss, struct wlp_uuid *wssid, | |||
| 447 | struct device *dev = &wlp->rc->uwb_dev.dev; | 415 | struct device *dev = &wlp->rc->uwb_dev.dev; |
| 448 | int result = 0; | 416 | int result = 0; |
| 449 | char buf[WLP_WSS_UUID_STRSIZE]; | 417 | char buf[WLP_WSS_UUID_STRSIZE]; |
| 450 | d_fnstart(5, dev, "Request to create new WSS.\n"); | 418 | |
| 451 | result = wlp_wss_uuid_print(buf, sizeof(buf), wssid); | 419 | result = wlp_wss_uuid_print(buf, sizeof(buf), wssid); |
| 452 | d_printf(5, dev, "Request to create WSS: WSSID=%s, name=%s, " | 420 | |
| 453 | "sec_status=%u, accepting enrollment=%u \n", | ||
| 454 | buf, name, sec_status, accept); | ||
| 455 | if (!mutex_trylock(&wss->mutex)) { | 421 | if (!mutex_trylock(&wss->mutex)) { |
| 456 | dev_err(dev, "WLP: WLP association session in progress.\n"); | 422 | dev_err(dev, "WLP: WLP association session in progress.\n"); |
| 457 | return -EBUSY; | 423 | return -EBUSY; |
| @@ -498,7 +464,6 @@ int wlp_wss_create_activate(struct wlp_wss *wss, struct wlp_uuid *wssid, | |||
| 498 | result = 0; | 464 | result = 0; |
| 499 | out: | 465 | out: |
| 500 | mutex_unlock(&wss->mutex); | 466 | mutex_unlock(&wss->mutex); |
| 501 | d_fnend(5, dev, "Completed. result = %d \n", result); | ||
| 502 | return result; | 467 | return result; |
| 503 | } | 468 | } |
| 504 | 469 | ||
| @@ -520,16 +485,12 @@ int wlp_wss_is_active(struct wlp *wlp, struct wlp_wss *wss, | |||
| 520 | { | 485 | { |
| 521 | int result = 0; | 486 | int result = 0; |
| 522 | struct device *dev = &wlp->rc->uwb_dev.dev; | 487 | struct device *dev = &wlp->rc->uwb_dev.dev; |
| 523 | char buf[WLP_WSS_UUID_STRSIZE]; | ||
| 524 | DECLARE_COMPLETION_ONSTACK(completion); | 488 | DECLARE_COMPLETION_ONSTACK(completion); |
| 525 | struct wlp_session session; | 489 | struct wlp_session session; |
| 526 | struct sk_buff *skb; | 490 | struct sk_buff *skb; |
| 527 | struct wlp_frame_assoc *resp; | 491 | struct wlp_frame_assoc *resp; |
| 528 | struct wlp_uuid wssid; | 492 | struct wlp_uuid wssid; |
| 529 | 493 | ||
| 530 | wlp_wss_uuid_print(buf, sizeof(buf), &wss->wssid); | ||
| 531 | d_fnstart(5, dev, "wlp %p, wss %p (wssid %s), neighbor %02x:%02x \n", | ||
| 532 | wlp, wss, buf, dev_addr->data[1], dev_addr->data[0]); | ||
| 533 | mutex_lock(&wlp->mutex); | 494 | mutex_lock(&wlp->mutex); |
| 534 | /* Send C1 association frame */ | 495 | /* Send C1 association frame */ |
| 535 | result = wlp_send_assoc_frame(wlp, wss, dev_addr, WLP_ASSOC_C1); | 496 | result = wlp_send_assoc_frame(wlp, wss, dev_addr, WLP_ASSOC_C1); |
| @@ -565,8 +526,6 @@ int wlp_wss_is_active(struct wlp *wlp, struct wlp_wss *wss, | |||
| 565 | /* Parse message in session->data: it will be either C2 or F0 */ | 526 | /* Parse message in session->data: it will be either C2 or F0 */ |
| 566 | skb = session.data; | 527 | skb = session.data; |
| 567 | resp = (void *) skb->data; | 528 | resp = (void *) skb->data; |
| 568 | d_printf(5, dev, "Received response to C1 frame. \n"); | ||
| 569 | d_dump(5, dev, skb->data, skb->len > 72 ? 72 : skb->len); | ||
| 570 | if (resp->type == WLP_ASSOC_F0) { | 529 | if (resp->type == WLP_ASSOC_F0) { |
| 571 | result = wlp_parse_f0(wlp, skb); | 530 | result = wlp_parse_f0(wlp, skb); |
| 572 | if (result < 0) | 531 | if (result < 0) |
| @@ -584,11 +543,9 @@ int wlp_wss_is_active(struct wlp *wlp, struct wlp_wss *wss, | |||
| 584 | result = 0; | 543 | result = 0; |
| 585 | goto error_resp_parse; | 544 | goto error_resp_parse; |
| 586 | } | 545 | } |
| 587 | if (!memcmp(&wssid, &wss->wssid, sizeof(wssid))) { | 546 | if (!memcmp(&wssid, &wss->wssid, sizeof(wssid))) |
| 588 | d_printf(5, dev, "WSSID in C2 frame matches local " | ||
| 589 | "active WSS.\n"); | ||
| 590 | result = 1; | 547 | result = 1; |
| 591 | } else { | 548 | else { |
| 592 | dev_err(dev, "WLP: Received a C2 frame without matching " | 549 | dev_err(dev, "WLP: Received a C2 frame without matching " |
| 593 | "WSSID.\n"); | 550 | "WSSID.\n"); |
| 594 | result = 0; | 551 | result = 0; |
| @@ -598,8 +555,6 @@ error_resp_parse: | |||
| 598 | out: | 555 | out: |
| 599 | wlp->session = NULL; | 556 | wlp->session = NULL; |
| 600 | mutex_unlock(&wlp->mutex); | 557 | mutex_unlock(&wlp->mutex); |
| 601 | d_fnend(5, dev, "wlp %p, wss %p (wssid %s), neighbor %02x:%02x \n", | ||
| 602 | wlp, wss, buf, dev_addr->data[1], dev_addr->data[0]); | ||
| 603 | return result; | 558 | return result; |
| 604 | } | 559 | } |
| 605 | 560 | ||
| @@ -620,16 +575,8 @@ int wlp_wss_activate_connection(struct wlp *wlp, struct wlp_wss *wss, | |||
| 620 | { | 575 | { |
| 621 | struct device *dev = &wlp->rc->uwb_dev.dev; | 576 | struct device *dev = &wlp->rc->uwb_dev.dev; |
| 622 | int result = 0; | 577 | int result = 0; |
| 623 | char buf[WLP_WSS_UUID_STRSIZE]; | ||
| 624 | wlp_wss_uuid_print(buf, sizeof(buf), wssid); | ||
| 625 | d_fnstart(5, dev, "wlp %p, wss %p, wssid %s, tag %u, virtual " | ||
| 626 | "%02x:%02x:%02x:%02x:%02x:%02x \n", wlp, wss, buf, *tag, | ||
| 627 | virt_addr->data[0], virt_addr->data[1], virt_addr->data[2], | ||
| 628 | virt_addr->data[3], virt_addr->data[4], virt_addr->data[5]); | ||
| 629 | 578 | ||
| 630 | if (!memcmp(wssid, &wss->wssid, sizeof(*wssid))) { | 579 | if (!memcmp(wssid, &wss->wssid, sizeof(*wssid))) { |
| 631 | d_printf(5, dev, "WSSID from neighbor frame matches local " | ||
| 632 | "active WSS.\n"); | ||
| 633 | /* Update EDA cache */ | 580 | /* Update EDA cache */ |
| 634 | result = wlp_eda_update_node(&wlp->eda, dev_addr, wss, | 581 | result = wlp_eda_update_node(&wlp->eda, dev_addr, wss, |
| 635 | (void *) virt_addr->data, *tag, | 582 | (void *) virt_addr->data, *tag, |
| @@ -638,18 +585,9 @@ int wlp_wss_activate_connection(struct wlp *wlp, struct wlp_wss *wss, | |||
| 638 | dev_err(dev, "WLP: Unable to update EDA cache " | 585 | dev_err(dev, "WLP: Unable to update EDA cache " |
| 639 | "with new connected neighbor information.\n"); | 586 | "with new connected neighbor information.\n"); |
| 640 | } else { | 587 | } else { |
| 641 | dev_err(dev, "WLP: Neighbor does not have matching " | 588 | dev_err(dev, "WLP: Neighbor does not have matching WSSID.\n"); |
| 642 | "WSSID.\n"); | ||
| 643 | result = -EINVAL; | 589 | result = -EINVAL; |
| 644 | } | 590 | } |
| 645 | |||
| 646 | d_fnend(5, dev, "wlp %p, wss %p, wssid %s, tag %u, virtual " | ||
| 647 | "%02x:%02x:%02x:%02x:%02x:%02x, result = %d \n", | ||
| 648 | wlp, wss, buf, *tag, | ||
| 649 | virt_addr->data[0], virt_addr->data[1], virt_addr->data[2], | ||
| 650 | virt_addr->data[3], virt_addr->data[4], virt_addr->data[5], | ||
| 651 | result); | ||
| 652 | |||
| 653 | return result; | 591 | return result; |
| 654 | } | 592 | } |
| 655 | 593 | ||
| @@ -665,7 +603,6 @@ int wlp_wss_connect_neighbor(struct wlp *wlp, struct wlp_wss *wss, | |||
| 665 | { | 603 | { |
| 666 | int result; | 604 | int result; |
| 667 | struct device *dev = &wlp->rc->uwb_dev.dev; | 605 | struct device *dev = &wlp->rc->uwb_dev.dev; |
| 668 | char buf[WLP_WSS_UUID_STRSIZE]; | ||
| 669 | struct wlp_uuid wssid; | 606 | struct wlp_uuid wssid; |
| 670 | u8 tag; | 607 | u8 tag; |
| 671 | struct uwb_mac_addr virt_addr; | 608 | struct uwb_mac_addr virt_addr; |
| @@ -674,9 +611,6 @@ int wlp_wss_connect_neighbor(struct wlp *wlp, struct wlp_wss *wss, | |||
| 674 | struct wlp_frame_assoc *resp; | 611 | struct wlp_frame_assoc *resp; |
| 675 | struct sk_buff *skb; | 612 | struct sk_buff *skb; |
| 676 | 613 | ||
| 677 | wlp_wss_uuid_print(buf, sizeof(buf), &wss->wssid); | ||
| 678 | d_fnstart(5, dev, "wlp %p, wss %p (wssid %s), neighbor %02x:%02x \n", | ||
| 679 | wlp, wss, buf, dev_addr->data[1], dev_addr->data[0]); | ||
| 680 | mutex_lock(&wlp->mutex); | 614 | mutex_lock(&wlp->mutex); |
| 681 | /* Send C3 association frame */ | 615 | /* Send C3 association frame */ |
| 682 | result = wlp_send_assoc_frame(wlp, wss, dev_addr, WLP_ASSOC_C3); | 616 | result = wlp_send_assoc_frame(wlp, wss, dev_addr, WLP_ASSOC_C3); |
| @@ -711,8 +645,6 @@ int wlp_wss_connect_neighbor(struct wlp *wlp, struct wlp_wss *wss, | |||
| 711 | /* Parse message in session->data: it will be either C4 or F0 */ | 645 | /* Parse message in session->data: it will be either C4 or F0 */ |
| 712 | skb = session.data; | 646 | skb = session.data; |
| 713 | resp = (void *) skb->data; | 647 | resp = (void *) skb->data; |
| 714 | d_printf(5, dev, "Received response to C3 frame. \n"); | ||
| 715 | d_dump(5, dev, skb->data, skb->len > 72 ? 72 : skb->len); | ||
| 716 | if (resp->type == WLP_ASSOC_F0) { | 648 | if (resp->type == WLP_ASSOC_F0) { |
| 717 | result = wlp_parse_f0(wlp, skb); | 649 | result = wlp_parse_f0(wlp, skb); |
| 718 | if (result < 0) | 650 | if (result < 0) |
| @@ -744,8 +676,6 @@ out: | |||
| 744 | WLP_WSS_CONNECT_FAILED); | 676 | WLP_WSS_CONNECT_FAILED); |
| 745 | wlp->session = NULL; | 677 | wlp->session = NULL; |
| 746 | mutex_unlock(&wlp->mutex); | 678 | mutex_unlock(&wlp->mutex); |
| 747 | d_fnend(5, dev, "wlp %p, wss %p (wssid %s), neighbor %02x:%02x \n", | ||
| 748 | wlp, wss, buf, dev_addr->data[1], dev_addr->data[0]); | ||
| 749 | return result; | 679 | return result; |
| 750 | } | 680 | } |
| 751 | 681 | ||
| @@ -780,12 +710,8 @@ void wlp_wss_connect_send(struct work_struct *ws) | |||
| 780 | struct wlp_wss *wss = &wlp->wss; | 710 | struct wlp_wss *wss = &wlp->wss; |
| 781 | int result; | 711 | int result; |
| 782 | struct device *dev = &wlp->rc->uwb_dev.dev; | 712 | struct device *dev = &wlp->rc->uwb_dev.dev; |
| 783 | char buf[WLP_WSS_UUID_STRSIZE]; | ||
| 784 | 713 | ||
| 785 | mutex_lock(&wss->mutex); | 714 | mutex_lock(&wss->mutex); |
| 786 | wlp_wss_uuid_print(buf, sizeof(buf), &wss->wssid); | ||
| 787 | d_fnstart(5, dev, "wlp %p, wss %p (wssid %s), neighbor %02x:%02x \n", | ||
| 788 | wlp, wss, buf, dev_addr->data[1], dev_addr->data[0]); | ||
| 789 | if (wss->state < WLP_WSS_STATE_ACTIVE) { | 715 | if (wss->state < WLP_WSS_STATE_ACTIVE) { |
| 790 | if (printk_ratelimit()) | 716 | if (printk_ratelimit()) |
| 791 | dev_err(dev, "WLP: Attempting to connect with " | 717 | dev_err(dev, "WLP: Attempting to connect with " |
| @@ -836,7 +762,6 @@ out: | |||
| 836 | BUG_ON(wlp->start_queue == NULL); | 762 | BUG_ON(wlp->start_queue == NULL); |
| 837 | wlp->start_queue(wlp); | 763 | wlp->start_queue(wlp); |
| 838 | mutex_unlock(&wss->mutex); | 764 | mutex_unlock(&wss->mutex); |
| 839 | d_fnend(5, dev, "wlp %p, wss %p (wssid %s)\n", wlp, wss, buf); | ||
| 840 | } | 765 | } |
| 841 | 766 | ||
| 842 | /** | 767 | /** |
| @@ -855,7 +780,6 @@ int wlp_wss_prep_hdr(struct wlp *wlp, struct wlp_eda_node *eda_entry, | |||
| 855 | struct sk_buff *skb = _skb; | 780 | struct sk_buff *skb = _skb; |
| 856 | struct wlp_frame_std_abbrv_hdr *std_hdr; | 781 | struct wlp_frame_std_abbrv_hdr *std_hdr; |
| 857 | 782 | ||
| 858 | d_fnstart(6, dev, "wlp %p \n", wlp); | ||
| 859 | if (eda_entry->state == WLP_WSS_CONNECTED) { | 783 | if (eda_entry->state == WLP_WSS_CONNECTED) { |
| 860 | /* Add WLP header */ | 784 | /* Add WLP header */ |
| 861 | BUG_ON(skb_headroom(skb) < sizeof(*std_hdr)); | 785 | BUG_ON(skb_headroom(skb) < sizeof(*std_hdr)); |
| @@ -873,7 +797,6 @@ int wlp_wss_prep_hdr(struct wlp *wlp, struct wlp_eda_node *eda_entry, | |||
| 873 | dev_addr->data[0]); | 797 | dev_addr->data[0]); |
| 874 | result = -EINVAL; | 798 | result = -EINVAL; |
| 875 | } | 799 | } |
| 876 | d_fnend(6, dev, "wlp %p \n", wlp); | ||
| 877 | return result; | 800 | return result; |
| 878 | } | 801 | } |
| 879 | 802 | ||
| @@ -893,16 +816,9 @@ int wlp_wss_connect_prep(struct wlp *wlp, struct wlp_eda_node *eda_entry, | |||
| 893 | { | 816 | { |
| 894 | int result = 0; | 817 | int result = 0; |
| 895 | struct device *dev = &wlp->rc->uwb_dev.dev; | 818 | struct device *dev = &wlp->rc->uwb_dev.dev; |
| 896 | struct uwb_dev_addr *dev_addr = &eda_entry->dev_addr; | ||
| 897 | unsigned char *eth_addr = eda_entry->eth_addr; | ||
| 898 | struct sk_buff *skb = _skb; | 819 | struct sk_buff *skb = _skb; |
| 899 | struct wlp_assoc_conn_ctx *conn_ctx; | 820 | struct wlp_assoc_conn_ctx *conn_ctx; |
| 900 | 821 | ||
| 901 | d_fnstart(5, dev, "wlp %p\n", wlp); | ||
| 902 | d_printf(5, dev, "To neighbor %02x:%02x with eth " | ||
| 903 | "%02x:%02x:%02x:%02x:%02x:%02x\n", dev_addr->data[1], | ||
| 904 | dev_addr->data[0], eth_addr[0], eth_addr[1], eth_addr[2], | ||
| 905 | eth_addr[3], eth_addr[4], eth_addr[5]); | ||
| 906 | if (eda_entry->state == WLP_WSS_UNCONNECTED) { | 822 | if (eda_entry->state == WLP_WSS_UNCONNECTED) { |
| 907 | /* We don't want any more packets while we set up connection */ | 823 | /* We don't want any more packets while we set up connection */ |
| 908 | BUG_ON(wlp->stop_queue == NULL); | 824 | BUG_ON(wlp->stop_queue == NULL); |
| @@ -929,12 +845,9 @@ int wlp_wss_connect_prep(struct wlp *wlp, struct wlp_eda_node *eda_entry, | |||
| 929 | "previously. Not retrying. \n"); | 845 | "previously. Not retrying. \n"); |
| 930 | result = -ENONET; | 846 | result = -ENONET; |
| 931 | goto out; | 847 | goto out; |
| 932 | } else { /* eda_entry->state == WLP_WSS_CONNECTED */ | 848 | } else /* eda_entry->state == WLP_WSS_CONNECTED */ |
| 933 | d_printf(5, dev, "Neighbor is connected, preparing frame.\n"); | ||
| 934 | result = wlp_wss_prep_hdr(wlp, eda_entry, skb); | 849 | result = wlp_wss_prep_hdr(wlp, eda_entry, skb); |
| 935 | } | ||
| 936 | out: | 850 | out: |
| 937 | d_fnend(5, dev, "wlp %p, result = %d \n", wlp, result); | ||
| 938 | return result; | 851 | return result; |
| 939 | } | 852 | } |
| 940 | 853 | ||
| @@ -957,8 +870,6 @@ int wlp_wss_send_copy(struct wlp *wlp, struct wlp_eda_node *eda_entry, | |||
| 957 | struct sk_buff *copy; | 870 | struct sk_buff *copy; |
| 958 | struct uwb_dev_addr *dev_addr = &eda_entry->dev_addr; | 871 | struct uwb_dev_addr *dev_addr = &eda_entry->dev_addr; |
| 959 | 872 | ||
| 960 | d_fnstart(5, dev, "to neighbor %02x:%02x, skb (%p) \n", | ||
| 961 | dev_addr->data[1], dev_addr->data[0], skb); | ||
| 962 | copy = skb_copy(skb, GFP_ATOMIC); | 873 | copy = skb_copy(skb, GFP_ATOMIC); |
| 963 | if (copy == NULL) { | 874 | if (copy == NULL) { |
| 964 | if (printk_ratelimit()) | 875 | if (printk_ratelimit()) |
| @@ -988,8 +899,6 @@ int wlp_wss_send_copy(struct wlp *wlp, struct wlp_eda_node *eda_entry, | |||
| 988 | dev_kfree_skb_irq(copy);/*we need to free if tx fails */ | 899 | dev_kfree_skb_irq(copy);/*we need to free if tx fails */ |
| 989 | } | 900 | } |
| 990 | out: | 901 | out: |
| 991 | d_fnend(5, dev, "to neighbor %02x:%02x \n", dev_addr->data[1], | ||
| 992 | dev_addr->data[0]); | ||
| 993 | return result; | 902 | return result; |
| 994 | } | 903 | } |
| 995 | 904 | ||
| @@ -1005,7 +914,7 @@ int wlp_wss_setup(struct net_device *net_dev, struct wlp_wss *wss) | |||
| 1005 | struct wlp *wlp = container_of(wss, struct wlp, wss); | 914 | struct wlp *wlp = container_of(wss, struct wlp, wss); |
| 1006 | struct device *dev = &wlp->rc->uwb_dev.dev; | 915 | struct device *dev = &wlp->rc->uwb_dev.dev; |
| 1007 | int result = 0; | 916 | int result = 0; |
| 1008 | d_fnstart(5, dev, "wss (%p) \n", wss); | 917 | |
| 1009 | mutex_lock(&wss->mutex); | 918 | mutex_lock(&wss->mutex); |
| 1010 | wss->kobj.parent = &net_dev->dev.kobj; | 919 | wss->kobj.parent = &net_dev->dev.kobj; |
| 1011 | if (!is_valid_ether_addr(net_dev->dev_addr)) { | 920 | if (!is_valid_ether_addr(net_dev->dev_addr)) { |
| @@ -1018,7 +927,6 @@ int wlp_wss_setup(struct net_device *net_dev, struct wlp_wss *wss) | |||
| 1018 | sizeof(wss->virtual_addr.data)); | 927 | sizeof(wss->virtual_addr.data)); |
| 1019 | out: | 928 | out: |
| 1020 | mutex_unlock(&wss->mutex); | 929 | mutex_unlock(&wss->mutex); |
| 1021 | d_fnend(5, dev, "wss (%p) \n", wss); | ||
| 1022 | return result; | 930 | return result; |
| 1023 | } | 931 | } |
| 1024 | EXPORT_SYMBOL_GPL(wlp_wss_setup); | 932 | EXPORT_SYMBOL_GPL(wlp_wss_setup); |
| @@ -1035,8 +943,7 @@ EXPORT_SYMBOL_GPL(wlp_wss_setup); | |||
| 1035 | void wlp_wss_remove(struct wlp_wss *wss) | 943 | void wlp_wss_remove(struct wlp_wss *wss) |
| 1036 | { | 944 | { |
| 1037 | struct wlp *wlp = container_of(wss, struct wlp, wss); | 945 | struct wlp *wlp = container_of(wss, struct wlp, wss); |
| 1038 | struct device *dev = &wlp->rc->uwb_dev.dev; | 946 | |
| 1039 | d_fnstart(5, dev, "wss (%p) \n", wss); | ||
| 1040 | mutex_lock(&wss->mutex); | 947 | mutex_lock(&wss->mutex); |
| 1041 | if (wss->state == WLP_WSS_STATE_ACTIVE) | 948 | if (wss->state == WLP_WSS_STATE_ACTIVE) |
| 1042 | uwb_rc_ie_rm(wlp->rc, UWB_IE_WLP); | 949 | uwb_rc_ie_rm(wlp->rc, UWB_IE_WLP); |
| @@ -1050,6 +957,5 @@ void wlp_wss_remove(struct wlp_wss *wss) | |||
| 1050 | wlp_eda_release(&wlp->eda); | 957 | wlp_eda_release(&wlp->eda); |
| 1051 | wlp_eda_init(&wlp->eda); | 958 | wlp_eda_init(&wlp->eda); |
| 1052 | mutex_unlock(&wss->mutex); | 959 | mutex_unlock(&wss->mutex); |
| 1053 | d_fnend(5, dev, "wss (%p) \n", wss); | ||
| 1054 | } | 960 | } |
| 1055 | EXPORT_SYMBOL_GPL(wlp_wss_remove); | 961 | EXPORT_SYMBOL_GPL(wlp_wss_remove); |
diff --git a/include/linux/usb/wusb-wa.h b/include/linux/usb/wusb-wa.h index a102561e702..fb7c359bdfb 100644 --- a/include/linux/usb/wusb-wa.h +++ b/include/linux/usb/wusb-wa.h | |||
| @@ -51,6 +51,7 @@ enum { | |||
| 51 | WUSB_REQ_GET_TIME = 25, | 51 | WUSB_REQ_GET_TIME = 25, |
| 52 | WUSB_REQ_SET_STREAM_IDX = 26, | 52 | WUSB_REQ_SET_STREAM_IDX = 26, |
| 53 | WUSB_REQ_SET_WUSB_MAS = 27, | 53 | WUSB_REQ_SET_WUSB_MAS = 27, |
| 54 | WUSB_REQ_CHAN_STOP = 28, | ||
| 54 | }; | 55 | }; |
| 55 | 56 | ||
| 56 | 57 | ||
diff --git a/include/linux/uwb.h b/include/linux/uwb.h index f9ccbd9a2ce..c02128991ff 100644 --- a/include/linux/uwb.h +++ b/include/linux/uwb.h | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | #include <linux/device.h> | 30 | #include <linux/device.h> |
| 31 | #include <linux/mutex.h> | 31 | #include <linux/mutex.h> |
| 32 | #include <linux/timer.h> | 32 | #include <linux/timer.h> |
| 33 | #include <linux/wait.h> | ||
| 33 | #include <linux/workqueue.h> | 34 | #include <linux/workqueue.h> |
| 34 | #include <linux/uwb/spec.h> | 35 | #include <linux/uwb/spec.h> |
| 35 | 36 | ||
| @@ -66,6 +67,7 @@ struct uwb_dev { | |||
| 66 | struct uwb_dev_addr dev_addr; | 67 | struct uwb_dev_addr dev_addr; |
| 67 | int beacon_slot; | 68 | int beacon_slot; |
| 68 | DECLARE_BITMAP(streams, UWB_NUM_STREAMS); | 69 | DECLARE_BITMAP(streams, UWB_NUM_STREAMS); |
| 70 | DECLARE_BITMAP(last_availability_bm, UWB_NUM_MAS); | ||
| 69 | }; | 71 | }; |
| 70 | #define to_uwb_dev(d) container_of(d, struct uwb_dev, dev) | 72 | #define to_uwb_dev(d) container_of(d, struct uwb_dev, dev) |
| 71 | 73 | ||
| @@ -86,12 +88,31 @@ struct uwb_notifs_chain { | |||
| 86 | struct mutex mutex; | 88 | struct mutex mutex; |
| 87 | }; | 89 | }; |
| 88 | 90 | ||
| 91 | /* Beacon cache list */ | ||
| 92 | struct uwb_beca { | ||
| 93 | struct list_head list; | ||
| 94 | size_t entries; | ||
| 95 | struct mutex mutex; | ||
| 96 | }; | ||
| 97 | |||
| 98 | /* Event handling thread. */ | ||
| 99 | struct uwbd { | ||
| 100 | int pid; | ||
| 101 | struct task_struct *task; | ||
| 102 | wait_queue_head_t wq; | ||
| 103 | struct list_head event_list; | ||
| 104 | spinlock_t event_list_lock; | ||
| 105 | }; | ||
| 106 | |||
| 89 | /** | 107 | /** |
| 90 | * struct uwb_mas_bm - a bitmap of all MAS in a superframe | 108 | * struct uwb_mas_bm - a bitmap of all MAS in a superframe |
| 91 | * @bm: a bitmap of length #UWB_NUM_MAS | 109 | * @bm: a bitmap of length #UWB_NUM_MAS |
| 92 | */ | 110 | */ |
| 93 | struct uwb_mas_bm { | 111 | struct uwb_mas_bm { |
| 94 | DECLARE_BITMAP(bm, UWB_NUM_MAS); | 112 | DECLARE_BITMAP(bm, UWB_NUM_MAS); |
| 113 | DECLARE_BITMAP(unsafe_bm, UWB_NUM_MAS); | ||
| 114 | int safe; | ||
| 115 | int unsafe; | ||
| 95 | }; | 116 | }; |
| 96 | 117 | ||
| 97 | /** | 118 | /** |
| @@ -117,14 +138,24 @@ struct uwb_mas_bm { | |||
| 117 | * FIXME: further target states TBD. | 138 | * FIXME: further target states TBD. |
| 118 | */ | 139 | */ |
| 119 | enum uwb_rsv_state { | 140 | enum uwb_rsv_state { |
| 120 | UWB_RSV_STATE_NONE, | 141 | UWB_RSV_STATE_NONE = 0, |
| 121 | UWB_RSV_STATE_O_INITIATED, | 142 | UWB_RSV_STATE_O_INITIATED, |
| 122 | UWB_RSV_STATE_O_PENDING, | 143 | UWB_RSV_STATE_O_PENDING, |
| 123 | UWB_RSV_STATE_O_MODIFIED, | 144 | UWB_RSV_STATE_O_MODIFIED, |
| 124 | UWB_RSV_STATE_O_ESTABLISHED, | 145 | UWB_RSV_STATE_O_ESTABLISHED, |
| 146 | UWB_RSV_STATE_O_TO_BE_MOVED, | ||
| 147 | UWB_RSV_STATE_O_MOVE_EXPANDING, | ||
| 148 | UWB_RSV_STATE_O_MOVE_COMBINING, | ||
| 149 | UWB_RSV_STATE_O_MOVE_REDUCING, | ||
| 125 | UWB_RSV_STATE_T_ACCEPTED, | 150 | UWB_RSV_STATE_T_ACCEPTED, |
| 126 | UWB_RSV_STATE_T_DENIED, | 151 | UWB_RSV_STATE_T_DENIED, |
| 152 | UWB_RSV_STATE_T_CONFLICT, | ||
| 127 | UWB_RSV_STATE_T_PENDING, | 153 | UWB_RSV_STATE_T_PENDING, |
| 154 | UWB_RSV_STATE_T_EXPANDING_ACCEPTED, | ||
| 155 | UWB_RSV_STATE_T_EXPANDING_CONFLICT, | ||
| 156 | UWB_RSV_STATE_T_EXPANDING_PENDING, | ||
| 157 | UWB_RSV_STATE_T_EXPANDING_DENIED, | ||
| 158 | UWB_RSV_STATE_T_RESIZED, | ||
| 128 | 159 | ||
| 129 | UWB_RSV_STATE_LAST, | 160 | UWB_RSV_STATE_LAST, |
| 130 | }; | 161 | }; |
| @@ -149,6 +180,12 @@ struct uwb_rsv_target { | |||
| 149 | }; | 180 | }; |
| 150 | }; | 181 | }; |
| 151 | 182 | ||
| 183 | struct uwb_rsv_move { | ||
| 184 | struct uwb_mas_bm final_mas; | ||
| 185 | struct uwb_ie_drp *companion_drp_ie; | ||
| 186 | struct uwb_mas_bm companion_mas; | ||
| 187 | }; | ||
| 188 | |||
| 152 | /* | 189 | /* |
| 153 | * Number of streams reserved for reservations targeted at DevAddrs. | 190 | * Number of streams reserved for reservations targeted at DevAddrs. |
| 154 | */ | 191 | */ |
| @@ -186,6 +223,7 @@ typedef void (*uwb_rsv_cb_f)(struct uwb_rsv *rsv); | |||
| 186 | * | 223 | * |
| 187 | * @status: negotiation status | 224 | * @status: negotiation status |
| 188 | * @stream: stream index allocated for this reservation | 225 | * @stream: stream index allocated for this reservation |
| 226 | * @tiebreaker: conflict tiebreaker for this reservation | ||
| 189 | * @mas: reserved MAS | 227 | * @mas: reserved MAS |
| 190 | * @drp_ie: the DRP IE | 228 | * @drp_ie: the DRP IE |
| 191 | * @ie_valid: true iff the DRP IE matches the reservation parameters | 229 | * @ie_valid: true iff the DRP IE matches the reservation parameters |
| @@ -201,25 +239,29 @@ struct uwb_rsv { | |||
| 201 | struct uwb_rc *rc; | 239 | struct uwb_rc *rc; |
| 202 | struct list_head rc_node; | 240 | struct list_head rc_node; |
| 203 | struct list_head pal_node; | 241 | struct list_head pal_node; |
| 242 | struct kref kref; | ||
| 204 | 243 | ||
| 205 | struct uwb_dev *owner; | 244 | struct uwb_dev *owner; |
| 206 | struct uwb_rsv_target target; | 245 | struct uwb_rsv_target target; |
| 207 | enum uwb_drp_type type; | 246 | enum uwb_drp_type type; |
| 208 | int max_mas; | 247 | int max_mas; |
| 209 | int min_mas; | 248 | int min_mas; |
| 210 | int sparsity; | 249 | int max_interval; |
| 211 | bool is_multicast; | 250 | bool is_multicast; |
| 212 | 251 | ||
| 213 | uwb_rsv_cb_f callback; | 252 | uwb_rsv_cb_f callback; |
| 214 | void *pal_priv; | 253 | void *pal_priv; |
| 215 | 254 | ||
| 216 | enum uwb_rsv_state state; | 255 | enum uwb_rsv_state state; |
| 256 | bool needs_release_companion_mas; | ||
| 217 | u8 stream; | 257 | u8 stream; |
| 258 | u8 tiebreaker; | ||
| 218 | struct uwb_mas_bm mas; | 259 | struct uwb_mas_bm mas; |
| 219 | struct uwb_ie_drp *drp_ie; | 260 | struct uwb_ie_drp *drp_ie; |
| 261 | struct uwb_rsv_move mv; | ||
| 220 | bool ie_valid; | 262 | bool ie_valid; |
| 221 | struct timer_list timer; | 263 | struct timer_list timer; |
| 222 | bool expired; | 264 | struct work_struct handle_timeout_work; |
| 223 | }; | 265 | }; |
| 224 | 266 | ||
| 225 | static const | 267 | static const |
| @@ -261,6 +303,13 @@ struct uwb_drp_avail { | |||
| 261 | bool ie_valid; | 303 | bool ie_valid; |
| 262 | }; | 304 | }; |
| 263 | 305 | ||
| 306 | struct uwb_drp_backoff_win { | ||
| 307 | u8 window; | ||
| 308 | u8 n; | ||
| 309 | int total_expired; | ||
| 310 | struct timer_list timer; | ||
| 311 | bool can_reserve_extra_mases; | ||
| 312 | }; | ||
| 264 | 313 | ||
| 265 | const char *uwb_rsv_state_str(enum uwb_rsv_state state); | 314 | const char *uwb_rsv_state_str(enum uwb_rsv_state state); |
| 266 | const char *uwb_rsv_type_str(enum uwb_drp_type type); | 315 | const char *uwb_rsv_type_str(enum uwb_drp_type type); |
| @@ -276,6 +325,8 @@ void uwb_rsv_terminate(struct uwb_rsv *rsv); | |||
| 276 | 325 | ||
| 277 | void uwb_rsv_accept(struct uwb_rsv *rsv, uwb_rsv_cb_f cb, void *pal_priv); | 326 | void uwb_rsv_accept(struct uwb_rsv *rsv, uwb_rsv_cb_f cb, void *pal_priv); |
| 278 | 327 | ||
| 328 | void uwb_rsv_get_usable_mas(struct uwb_rsv *orig_rsv, struct uwb_mas_bm *mas); | ||
| 329 | |||
| 279 | /** | 330 | /** |
| 280 | * Radio Control Interface instance | 331 | * Radio Control Interface instance |
| 281 | * | 332 | * |
| @@ -337,23 +388,33 @@ struct uwb_rc { | |||
| 337 | u8 ctx_roll; | 388 | u8 ctx_roll; |
| 338 | 389 | ||
| 339 | int beaconing; /* Beaconing state [channel number] */ | 390 | int beaconing; /* Beaconing state [channel number] */ |
| 391 | int beaconing_forced; | ||
| 340 | int scanning; | 392 | int scanning; |
| 341 | enum uwb_scan_type scan_type:3; | 393 | enum uwb_scan_type scan_type:3; |
| 342 | unsigned ready:1; | 394 | unsigned ready:1; |
| 343 | struct uwb_notifs_chain notifs_chain; | 395 | struct uwb_notifs_chain notifs_chain; |
| 396 | struct uwb_beca uwb_beca; | ||
| 397 | |||
| 398 | struct uwbd uwbd; | ||
| 344 | 399 | ||
| 400 | struct uwb_drp_backoff_win bow; | ||
| 345 | struct uwb_drp_avail drp_avail; | 401 | struct uwb_drp_avail drp_avail; |
| 346 | struct list_head reservations; | 402 | struct list_head reservations; |
| 403 | struct list_head cnflt_alien_list; | ||
| 404 | struct uwb_mas_bm cnflt_alien_bitmap; | ||
| 347 | struct mutex rsvs_mutex; | 405 | struct mutex rsvs_mutex; |
| 406 | spinlock_t rsvs_lock; | ||
| 348 | struct workqueue_struct *rsv_workq; | 407 | struct workqueue_struct *rsv_workq; |
| 349 | struct work_struct rsv_update_work; | ||
| 350 | 408 | ||
| 409 | struct delayed_work rsv_update_work; | ||
| 410 | struct delayed_work rsv_alien_bp_work; | ||
| 411 | int set_drp_ie_pending; | ||
| 351 | struct mutex ies_mutex; | 412 | struct mutex ies_mutex; |
| 352 | struct uwb_rc_cmd_set_ie *ies; | 413 | struct uwb_rc_cmd_set_ie *ies; |
| 353 | size_t ies_capacity; | 414 | size_t ies_capacity; |
| 354 | 415 | ||
| 355 | spinlock_t pal_lock; | ||
| 356 | struct list_head pals; | 416 | struct list_head pals; |
| 417 | int active_pals; | ||
| 357 | 418 | ||
| 358 | struct uwb_dbg *dbg; | 419 | struct uwb_dbg *dbg; |
| 359 | }; | 420 | }; |
| @@ -361,11 +422,19 @@ struct uwb_rc { | |||
| 361 | 422 | ||
| 362 | /** | 423 | /** |
| 363 | * struct uwb_pal - a UWB PAL | 424 | * struct uwb_pal - a UWB PAL |
| 364 | * @name: descriptive name for this PAL (wushc, wlp, etc.). | 425 | * @name: descriptive name for this PAL (wusbhc, wlp, etc.). |
| 365 | * @device: a device for the PAL. Used to link the PAL and the radio | 426 | * @device: a device for the PAL. Used to link the PAL and the radio |
| 366 | * controller in sysfs. | 427 | * controller in sysfs. |
| 428 | * @rc: the radio controller the PAL uses. | ||
| 429 | * @channel_changed: called when the channel used by the radio changes. | ||
| 430 | * A channel of -1 means the channel has been stopped. | ||
| 367 | * @new_rsv: called when a peer requests a reservation (may be NULL if | 431 | * @new_rsv: called when a peer requests a reservation (may be NULL if |
| 368 | * the PAL cannot accept reservation requests). | 432 | * the PAL cannot accept reservation requests). |
| 433 | * @channel: channel being used by the PAL; 0 if the PAL isn't using | ||
| 434 | * the radio; -1 if the PAL wishes to use the radio but | ||
| 435 | * cannot. | ||
| 436 | * @debugfs_dir: a debugfs directory which the PAL can use for its own | ||
| 437 | * debugfs files. | ||
| 369 | * | 438 | * |
| 370 | * A Protocol Adaptation Layer (PAL) is a user of the WiMedia UWB | 439 | * A Protocol Adaptation Layer (PAL) is a user of the WiMedia UWB |
| 371 | * radio platform (e.g., WUSB, WLP or Bluetooth UWB AMP). | 440 | * radio platform (e.g., WUSB, WLP or Bluetooth UWB AMP). |
| @@ -384,12 +453,21 @@ struct uwb_pal { | |||
| 384 | struct list_head node; | 453 | struct list_head node; |
| 385 | const char *name; | 454 | const char *name; |
| 386 | struct device *device; | 455 | struct device *device; |
| 387 | void (*new_rsv)(struct uwb_rsv *rsv); | 456 | struct uwb_rc *rc; |
| 457 | |||
| 458 | void (*channel_changed)(struct uwb_pal *pal, int channel); | ||
| 459 | void (*new_rsv)(struct uwb_pal *pal, struct uwb_rsv *rsv); | ||
| 460 | |||
| 461 | int channel; | ||
| 462 | struct dentry *debugfs_dir; | ||
| 388 | }; | 463 | }; |
| 389 | 464 | ||
| 390 | void uwb_pal_init(struct uwb_pal *pal); | 465 | void uwb_pal_init(struct uwb_pal *pal); |
| 391 | int uwb_pal_register(struct uwb_rc *rc, struct uwb_pal *pal); | 466 | int uwb_pal_register(struct uwb_pal *pal); |
| 392 | void uwb_pal_unregister(struct uwb_rc *rc, struct uwb_pal *pal); | 467 | void uwb_pal_unregister(struct uwb_pal *pal); |
| 468 | |||
| 469 | int uwb_radio_start(struct uwb_pal *pal); | ||
| 470 | void uwb_radio_stop(struct uwb_pal *pal); | ||
| 393 | 471 | ||
| 394 | /* | 472 | /* |
| 395 | * General public API | 473 | * General public API |
| @@ -443,8 +521,6 @@ ssize_t uwb_rc_vcmd(struct uwb_rc *rc, const char *cmd_name, | |||
| 443 | struct uwb_rccb *cmd, size_t cmd_size, | 521 | struct uwb_rccb *cmd, size_t cmd_size, |
| 444 | u8 expected_type, u16 expected_event, | 522 | u8 expected_type, u16 expected_event, |
| 445 | struct uwb_rceb **preply); | 523 | struct uwb_rceb **preply); |
| 446 | ssize_t uwb_rc_get_ie(struct uwb_rc *, struct uwb_rc_evt_get_ie **); | ||
| 447 | int uwb_bg_joined(struct uwb_rc *rc); | ||
| 448 | 524 | ||
| 449 | size_t __uwb_addr_print(char *, size_t, const unsigned char *, int); | 525 | size_t __uwb_addr_print(char *, size_t, const unsigned char *, int); |
| 450 | 526 | ||
| @@ -520,6 +596,8 @@ void uwb_rc_rm(struct uwb_rc *); | |||
| 520 | void uwb_rc_neh_grok(struct uwb_rc *, void *, size_t); | 596 | void uwb_rc_neh_grok(struct uwb_rc *, void *, size_t); |
| 521 | void uwb_rc_neh_error(struct uwb_rc *, int); | 597 | void uwb_rc_neh_error(struct uwb_rc *, int); |
| 522 | void uwb_rc_reset_all(struct uwb_rc *rc); | 598 | void uwb_rc_reset_all(struct uwb_rc *rc); |
| 599 | void uwb_rc_pre_reset(struct uwb_rc *rc); | ||
| 600 | void uwb_rc_post_reset(struct uwb_rc *rc); | ||
| 523 | 601 | ||
| 524 | /** | 602 | /** |
| 525 | * uwb_rsv_is_owner - is the owner of this reservation the RC? | 603 | * uwb_rsv_is_owner - is the owner of this reservation the RC? |
| @@ -531,7 +609,9 @@ static inline bool uwb_rsv_is_owner(struct uwb_rsv *rsv) | |||
| 531 | } | 609 | } |
| 532 | 610 | ||
| 533 | /** | 611 | /** |
| 534 | * Events generated by UWB that can be passed to any listeners | 612 | * enum uwb_notifs - UWB events that can be passed to any listeners |
| 613 | * @UWB_NOTIF_ONAIR: a new neighbour has joined the beacon group. | ||
| 614 | * @UWB_NOTIF_OFFAIR: a neighbour has left the beacon group. | ||
| 535 | * | 615 | * |
| 536 | * Higher layers can register callback functions with the radio | 616 | * Higher layers can register callback functions with the radio |
| 537 | * controller using uwb_notifs_register(). The radio controller | 617 | * controller using uwb_notifs_register(). The radio controller |
| @@ -539,8 +619,6 @@ static inline bool uwb_rsv_is_owner(struct uwb_rsv *rsv) | |||
| 539 | * nodes when an event occurs. | 619 | * nodes when an event occurs. |
| 540 | */ | 620 | */ |
| 541 | enum uwb_notifs { | 621 | enum uwb_notifs { |
| 542 | UWB_NOTIF_BG_JOIN = 0, /* radio controller joined a beacon group */ | ||
| 543 | UWB_NOTIF_BG_LEAVE = 1, /* radio controller left a beacon group */ | ||
| 544 | UWB_NOTIF_ONAIR, | 622 | UWB_NOTIF_ONAIR, |
| 545 | UWB_NOTIF_OFFAIR, | 623 | UWB_NOTIF_OFFAIR, |
| 546 | }; | 624 | }; |
| @@ -652,22 +730,9 @@ static inline int edc_inc(struct edc *err_hist, u16 max_err, u16 timeframe) | |||
| 652 | 730 | ||
| 653 | /* Information Element handling */ | 731 | /* Information Element handling */ |
| 654 | 732 | ||
| 655 | /* For representing the state of writing to a buffer when iterating */ | ||
| 656 | struct uwb_buf_ctx { | ||
| 657 | char *buf; | ||
| 658 | size_t bytes, size; | ||
| 659 | }; | ||
| 660 | |||
| 661 | typedef int (*uwb_ie_f)(struct uwb_dev *, const struct uwb_ie_hdr *, | ||
| 662 | size_t, void *); | ||
| 663 | struct uwb_ie_hdr *uwb_ie_next(void **ptr, size_t *len); | 733 | struct uwb_ie_hdr *uwb_ie_next(void **ptr, size_t *len); |
| 664 | ssize_t uwb_ie_for_each(struct uwb_dev *uwb_dev, uwb_ie_f fn, void *data, | 734 | int uwb_rc_ie_add(struct uwb_rc *uwb_rc, const struct uwb_ie_hdr *ies, size_t size); |
| 665 | const void *buf, size_t size); | 735 | int uwb_rc_ie_rm(struct uwb_rc *uwb_rc, enum uwb_ie element_id); |
| 666 | int uwb_ie_dump_hex(struct uwb_dev *, const struct uwb_ie_hdr *, | ||
| 667 | size_t, void *); | ||
| 668 | int uwb_rc_set_ie(struct uwb_rc *, struct uwb_rc_cmd_set_ie *); | ||
| 669 | struct uwb_ie_hdr *uwb_ie_next(void **ptr, size_t *len); | ||
| 670 | |||
| 671 | 736 | ||
| 672 | /* | 737 | /* |
| 673 | * Transmission statistics | 738 | * Transmission statistics |
diff --git a/include/linux/uwb/debug-cmd.h b/include/linux/uwb/debug-cmd.h index 1141f41bab5..8da004e2562 100644 --- a/include/linux/uwb/debug-cmd.h +++ b/include/linux/uwb/debug-cmd.h | |||
| @@ -32,6 +32,10 @@ | |||
| 32 | enum uwb_dbg_cmd_type { | 32 | enum uwb_dbg_cmd_type { |
| 33 | UWB_DBG_CMD_RSV_ESTABLISH = 1, | 33 | UWB_DBG_CMD_RSV_ESTABLISH = 1, |
| 34 | UWB_DBG_CMD_RSV_TERMINATE = 2, | 34 | UWB_DBG_CMD_RSV_TERMINATE = 2, |
| 35 | UWB_DBG_CMD_IE_ADD = 3, | ||
| 36 | UWB_DBG_CMD_IE_RM = 4, | ||
| 37 | UWB_DBG_CMD_RADIO_START = 5, | ||
| 38 | UWB_DBG_CMD_RADIO_STOP = 6, | ||
| 35 | }; | 39 | }; |
| 36 | 40 | ||
| 37 | struct uwb_dbg_cmd_rsv_establish { | 41 | struct uwb_dbg_cmd_rsv_establish { |
| @@ -39,18 +43,25 @@ struct uwb_dbg_cmd_rsv_establish { | |||
| 39 | __u8 type; | 43 | __u8 type; |
| 40 | __u16 max_mas; | 44 | __u16 max_mas; |
| 41 | __u16 min_mas; | 45 | __u16 min_mas; |
| 42 | __u8 sparsity; | 46 | __u8 max_interval; |
| 43 | }; | 47 | }; |
| 44 | 48 | ||
| 45 | struct uwb_dbg_cmd_rsv_terminate { | 49 | struct uwb_dbg_cmd_rsv_terminate { |
| 46 | int index; | 50 | int index; |
| 47 | }; | 51 | }; |
| 48 | 52 | ||
| 53 | struct uwb_dbg_cmd_ie { | ||
| 54 | __u8 data[128]; | ||
| 55 | int len; | ||
| 56 | }; | ||
| 57 | |||
| 49 | struct uwb_dbg_cmd { | 58 | struct uwb_dbg_cmd { |
| 50 | __u32 type; | 59 | __u32 type; |
| 51 | union { | 60 | union { |
| 52 | struct uwb_dbg_cmd_rsv_establish rsv_establish; | 61 | struct uwb_dbg_cmd_rsv_establish rsv_establish; |
| 53 | struct uwb_dbg_cmd_rsv_terminate rsv_terminate; | 62 | struct uwb_dbg_cmd_rsv_terminate rsv_terminate; |
| 63 | struct uwb_dbg_cmd_ie ie_add; | ||
| 64 | struct uwb_dbg_cmd_ie ie_rm; | ||
| 54 | }; | 65 | }; |
| 55 | }; | 66 | }; |
| 56 | 67 | ||
diff --git a/include/linux/uwb/debug.h b/include/linux/uwb/debug.h deleted file mode 100644 index a86a73fe303..00000000000 --- a/include/linux/uwb/debug.h +++ /dev/null | |||
| @@ -1,82 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Ultra Wide Band | ||
| 3 | * Debug Support | ||
| 4 | * | ||
| 5 | * Copyright (C) 2005-2006 Intel Corporation | ||
| 6 | * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or | ||
| 9 | * modify it under the terms of the GNU General Public License version | ||
| 10 | * 2 as published by the Free Software Foundation. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
| 20 | * 02110-1301, USA. | ||
| 21 | * | ||
| 22 | * | ||
| 23 | * FIXME: doc | ||
| 24 | * Invoke like: | ||
| 25 | * | ||
| 26 | * #define D_LOCAL 4 | ||
| 27 | * #include <linux/uwb/debug.h> | ||
| 28 | * | ||
| 29 | * At the end of your include files. | ||
| 30 | */ | ||
| 31 | #include <linux/types.h> | ||
| 32 | |||
| 33 | struct device; | ||
| 34 | extern void dump_bytes(struct device *dev, const void *_buf, size_t rsize); | ||
| 35 | |||
| 36 | /* Master debug switch; !0 enables, 0 disables */ | ||
| 37 | #define D_MASTER (!0) | ||
| 38 | |||
| 39 | /* Local (per-file) debug switch; #define before #including */ | ||
| 40 | #ifndef D_LOCAL | ||
| 41 | #define D_LOCAL 0 | ||
| 42 | #endif | ||
| 43 | |||
| 44 | #undef __d_printf | ||
| 45 | #undef d_fnstart | ||
| 46 | #undef d_fnend | ||
| 47 | #undef d_printf | ||
| 48 | #undef d_dump | ||
| 49 | |||
| 50 | #define __d_printf(l, _tag, _dev, f, a...) \ | ||
| 51 | do { \ | ||
| 52 | struct device *__dev = (_dev); \ | ||
| 53 | if (D_MASTER && D_LOCAL >= (l)) { \ | ||
| 54 | char __head[64] = ""; \ | ||
| 55 | if (_dev != NULL) { \ | ||
| 56 | if ((unsigned long)__dev < 4096) \ | ||
| 57 | printk(KERN_ERR "E: Corrupt dev %p\n", \ | ||
| 58 | __dev); \ | ||
| 59 | else \ | ||
| 60 | snprintf(__head, sizeof(__head), \ | ||
| 61 | "%s %s: ", \ | ||
| 62 | dev_driver_string(__dev), \ | ||
| 63 | __dev->bus_id); \ | ||
| 64 | } \ | ||
| 65 | printk(KERN_ERR "%s%s" _tag ": " f, __head, \ | ||
| 66 | __func__, ## a); \ | ||
| 67 | } \ | ||
| 68 | } while (0 && _dev) | ||
| 69 | |||
| 70 | #define d_fnstart(l, _dev, f, a...) \ | ||
| 71 | __d_printf(l, " FNSTART", _dev, f, ## a) | ||
| 72 | #define d_fnend(l, _dev, f, a...) \ | ||
| 73 | __d_printf(l, " FNEND", _dev, f, ## a) | ||
| 74 | #define d_printf(l, _dev, f, a...) \ | ||
| 75 | __d_printf(l, "", _dev, f, ## a) | ||
| 76 | #define d_dump(l, _dev, ptr, size) \ | ||
| 77 | do { \ | ||
| 78 | struct device *__dev = _dev; \ | ||
| 79 | if (D_MASTER && D_LOCAL >= (l)) \ | ||
| 80 | dump_bytes(__dev, ptr, size); \ | ||
| 81 | } while (0 && _dev) | ||
| 82 | #define d_test(l) (D_MASTER && D_LOCAL >= (l)) | ||
diff --git a/include/linux/uwb/spec.h b/include/linux/uwb/spec.h index 198c15f8e25..b52e44f1bd3 100644 --- a/include/linux/uwb/spec.h +++ b/include/linux/uwb/spec.h | |||
| @@ -59,6 +59,11 @@ enum { UWB_NUM_ZONES = 16 }; | |||
| 59 | #define UWB_MAS_PER_ZONE (UWB_NUM_MAS / UWB_NUM_ZONES) | 59 | #define UWB_MAS_PER_ZONE (UWB_NUM_MAS / UWB_NUM_ZONES) |
| 60 | 60 | ||
| 61 | /* | 61 | /* |
| 62 | * Number of MAS required before a row can be considered available. | ||
| 63 | */ | ||
| 64 | #define UWB_USABLE_MAS_PER_ROW (UWB_NUM_ZONES - 1) | ||
| 65 | |||
| 66 | /* | ||
| 62 | * Number of streams per DRP reservation between a pair of devices. | 67 | * Number of streams per DRP reservation between a pair of devices. |
| 63 | * | 68 | * |
| 64 | * [ECMA-368] section 16.8.6. | 69 | * [ECMA-368] section 16.8.6. |
| @@ -94,6 +99,26 @@ enum { UWB_BEACON_SLOT_LENGTH_US = 85 }; | |||
| 94 | enum { UWB_MAX_LOST_BEACONS = 3 }; | 99 | enum { UWB_MAX_LOST_BEACONS = 3 }; |
| 95 | 100 | ||
| 96 | /* | 101 | /* |
| 102 | * mDRPBackOffWinMin | ||
| 103 | * | ||
| 104 | * The minimum number of superframes to wait before trying to reserve | ||
| 105 | * extra MAS. | ||
| 106 | * | ||
| 107 | * [ECMA-368] section 17.16 | ||
| 108 | */ | ||
| 109 | enum { UWB_DRP_BACKOFF_WIN_MIN = 2 }; | ||
| 110 | |||
| 111 | /* | ||
| 112 | * mDRPBackOffWinMax | ||
| 113 | * | ||
| 114 | * The maximum number of superframes to wait before trying to reserve | ||
| 115 | * extra MAS. | ||
| 116 | * | ||
| 117 | * [ECMA-368] section 17.16 | ||
| 118 | */ | ||
| 119 | enum { UWB_DRP_BACKOFF_WIN_MAX = 16 }; | ||
| 120 | |||
| 121 | /* | ||
| 97 | * Length of a superframe in microseconds. | 122 | * Length of a superframe in microseconds. |
| 98 | */ | 123 | */ |
| 99 | #define UWB_SUPERFRAME_LENGTH_US (UWB_MAS_LENGTH_US * UWB_NUM_MAS) | 124 | #define UWB_SUPERFRAME_LENGTH_US (UWB_MAS_LENGTH_US * UWB_NUM_MAS) |
| @@ -200,6 +225,12 @@ enum uwb_drp_reason { | |||
| 200 | UWB_DRP_REASON_MODIFIED, | 225 | UWB_DRP_REASON_MODIFIED, |
| 201 | }; | 226 | }; |
| 202 | 227 | ||
| 228 | /** Relinquish Request Reason Codes ([ECMA-368] table 113) */ | ||
| 229 | enum uwb_relinquish_req_reason { | ||
| 230 | UWB_RELINQUISH_REQ_REASON_NON_SPECIFIC = 0, | ||
| 231 | UWB_RELINQUISH_REQ_REASON_OVER_ALLOCATION, | ||
| 232 | }; | ||
| 233 | |||
| 203 | /** | 234 | /** |
| 204 | * DRP Notification Reason Codes (WHCI 0.95 [3.1.4.9]) | 235 | * DRP Notification Reason Codes (WHCI 0.95 [3.1.4.9]) |
| 205 | */ | 236 | */ |
| @@ -252,6 +283,7 @@ enum uwb_ie { | |||
| 252 | UWB_APP_SPEC_PROBE_IE = 15, | 283 | UWB_APP_SPEC_PROBE_IE = 15, |
| 253 | UWB_IDENTIFICATION_IE = 19, | 284 | UWB_IDENTIFICATION_IE = 19, |
| 254 | UWB_MASTER_KEY_ID_IE = 20, | 285 | UWB_MASTER_KEY_ID_IE = 20, |
| 286 | UWB_RELINQUISH_REQUEST_IE = 21, | ||
| 255 | UWB_IE_WLP = 250, /* WiMedia Logical Link Control Protocol WLP 0.99 */ | 287 | UWB_IE_WLP = 250, /* WiMedia Logical Link Control Protocol WLP 0.99 */ |
| 256 | UWB_APP_SPEC_IE = 255, | 288 | UWB_APP_SPEC_IE = 255, |
| 257 | }; | 289 | }; |
| @@ -365,6 +397,27 @@ struct uwb_ie_drp_avail { | |||
| 365 | DECLARE_BITMAP(bmp, UWB_NUM_MAS); | 397 | DECLARE_BITMAP(bmp, UWB_NUM_MAS); |
| 366 | } __attribute__((packed)); | 398 | } __attribute__((packed)); |
| 367 | 399 | ||
| 400 | /* Relinqish Request IE ([ECMA-368] section 16.8.19). */ | ||
| 401 | struct uwb_relinquish_request_ie { | ||
| 402 | struct uwb_ie_hdr hdr; | ||
| 403 | __le16 relinquish_req_control; | ||
| 404 | struct uwb_dev_addr dev_addr; | ||
| 405 | struct uwb_drp_alloc allocs[]; | ||
| 406 | } __attribute__((packed)); | ||
| 407 | |||
| 408 | static inline int uwb_ie_relinquish_req_reason_code(struct uwb_relinquish_request_ie *ie) | ||
| 409 | { | ||
| 410 | return (le16_to_cpu(ie->relinquish_req_control) >> 0) & 0xf; | ||
| 411 | } | ||
| 412 | |||
| 413 | static inline void uwb_ie_relinquish_req_set_reason_code(struct uwb_relinquish_request_ie *ie, | ||
| 414 | int reason_code) | ||
| 415 | { | ||
| 416 | u16 ctrl = le16_to_cpu(ie->relinquish_req_control); | ||
| 417 | ctrl = (ctrl & ~(0xf << 0)) | (reason_code << 0); | ||
| 418 | ie->relinquish_req_control = cpu_to_le16(ctrl); | ||
| 419 | } | ||
| 420 | |||
| 368 | /** | 421 | /** |
| 369 | * The Vendor ID is set to an OUI that indicates the vendor of the device. | 422 | * The Vendor ID is set to an OUI that indicates the vendor of the device. |
| 370 | * ECMA-368 [16.8.10] | 423 | * ECMA-368 [16.8.10] |
diff --git a/include/linux/uwb/umc.h b/include/linux/uwb/umc.h index 36a39e34f8d..4b4fc0f4385 100644 --- a/include/linux/uwb/umc.h +++ b/include/linux/uwb/umc.h | |||
| @@ -89,6 +89,8 @@ struct umc_driver { | |||
| 89 | void (*remove)(struct umc_dev *); | 89 | void (*remove)(struct umc_dev *); |
| 90 | int (*suspend)(struct umc_dev *, pm_message_t state); | 90 | int (*suspend)(struct umc_dev *, pm_message_t state); |
| 91 | int (*resume)(struct umc_dev *); | 91 | int (*resume)(struct umc_dev *); |
| 92 | int (*pre_reset)(struct umc_dev *); | ||
| 93 | int (*post_reset)(struct umc_dev *); | ||
| 92 | 94 | ||
| 93 | struct device_driver driver; | 95 | struct device_driver driver; |
| 94 | }; | 96 | }; |
diff --git a/include/linux/wlp.h b/include/linux/wlp.h index 033545e145c..ac95ce6606a 100644 --- a/include/linux/wlp.h +++ b/include/linux/wlp.h | |||
| @@ -646,6 +646,7 @@ struct wlp_wss { | |||
| 646 | struct wlp { | 646 | struct wlp { |
| 647 | struct mutex mutex; | 647 | struct mutex mutex; |
| 648 | struct uwb_rc *rc; /* UWB radio controller */ | 648 | struct uwb_rc *rc; /* UWB radio controller */ |
| 649 | struct net_device *ndev; | ||
| 649 | struct uwb_pal pal; | 650 | struct uwb_pal pal; |
| 650 | struct wlp_eda eda; | 651 | struct wlp_eda eda; |
| 651 | struct wlp_uuid uuid; | 652 | struct wlp_uuid uuid; |
| @@ -675,7 +676,7 @@ struct wlp_wss_attribute { | |||
| 675 | static struct wlp_wss_attribute wss_attr_##_name = __ATTR(_name, _mode, \ | 676 | static struct wlp_wss_attribute wss_attr_##_name = __ATTR(_name, _mode, \ |
| 676 | _show, _store) | 677 | _show, _store) |
| 677 | 678 | ||
| 678 | extern int wlp_setup(struct wlp *, struct uwb_rc *); | 679 | extern int wlp_setup(struct wlp *, struct uwb_rc *, struct net_device *ndev); |
| 679 | extern void wlp_remove(struct wlp *); | 680 | extern void wlp_remove(struct wlp *); |
| 680 | extern ssize_t wlp_neighborhood_show(struct wlp *, char *); | 681 | extern ssize_t wlp_neighborhood_show(struct wlp *, char *); |
| 681 | extern int wlp_wss_setup(struct net_device *, struct wlp_wss *); | 682 | extern int wlp_wss_setup(struct net_device *, struct wlp_wss *); |
