aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/hwa-hc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/hwa-hc.c')
-rw-r--r--drivers/usb/host/hwa-hc.c159
1 files changed, 55 insertions, 104 deletions
diff --git a/drivers/usb/host/hwa-hc.c b/drivers/usb/host/hwa-hc.c
index 64be4d88df11..8582236e4cad 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
69struct hwahc { 65struct 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 }
143error_unlock: 136error_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;
183out: 164out:
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
188error_stop:
189 __wa_stop(&hwahc->wa);
190error_set_cluster_id: 168error_set_cluster_id:
191 wusb_cluster_id_put(wusbhc->cluster_id); 169 wusb_cluster_id_put(wusbhc->cluster_id);
192error_cluster_id_get: 170error_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 */
200static 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;
221out:
222 d_fnend(4, dev, "(hwahc %p) = %d\n", hwahc, result);
223 return result;
224
225error_stop:
226 result = __wa_clear_feature(&hwahc->wa, WA_ENABLE);
227 goto out;
228}
229
230static int hwahc_op_suspend(struct usb_hcd *usb_hcd, pm_message_t msg) 175static 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
249static 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 */
267static void hwahc_op_stop(struct usb_hcd *usb_hcd) 200static 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
286static int hwahc_op_get_frame_number(struct usb_hcd *usb_hcd) 209static 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
251static 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
274error_stop:
275 __wa_clear_feature(&hwahc->wa, WA_ENABLE);
276 return result;
277}
278
279static 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
810static void hwahc_init(struct hwahc *hwahc) 779static 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
854error_wusbhc_b_create: 821error_wusbhc_b_create:
@@ -858,7 +825,6 @@ error_add_hcd:
858error_hwahc_create: 825error_hwahc_create:
859 usb_put_hcd(usb_hcd); 826 usb_put_hcd(usb_hcd);
860error_alloc: 827error_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 */
885static struct usb_device_id hwahc_id_table[] = { 847static 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
899static int __init hwahc_driver_init(void) 861static 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
910error_usb_register:
911 return result;
912
913} 864}
914module_init(hwahc_driver_init); 865module_init(hwahc_driver_init);
915 866