silicom: checkpatch: trailing statements
[deliverable/linux.git] / drivers / staging / octeon-usb / octeon-hcd.c
CommitLineData
b164935b
AK
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2008 Cavium Networks
7 */
8#include <linux/kernel.h>
9#include <linux/module.h>
10#include <linux/init.h>
11#include <linux/pci.h>
12#include <linux/interrupt.h>
13#include <linux/platform_device.h>
b164935b
AK
14#include <linux/usb.h>
15
2a81d2b0
AK
16#include <linux/time.h>
17#include <linux/delay.h>
b164935b
AK
18
19#include <asm/octeon/cvmx.h>
20#include "cvmx-usb.h"
21#include <asm/octeon/cvmx-iob-defs.h>
22
23#include <linux/usb/hcd.h>
24
55fa328a
DN
25#include <linux/err.h>
26
b164935b
AK
27//#define DEBUG_CALL(format, ...) printk(format, ##__VA_ARGS__)
28#define DEBUG_CALL(format, ...) do {} while (0)
29//#define DEBUG_SUBMIT(format, ...) printk(format, ##__VA_ARGS__)
30#define DEBUG_SUBMIT(format, ...) do {} while (0)
31//#define DEBUG_ROOT_HUB(format, ...) printk(format, ##__VA_ARGS__)
32#define DEBUG_ROOT_HUB(format, ...) do {} while (0)
33//#define DEBUG_ERROR(format, ...) printk(format, ##__VA_ARGS__)
34#define DEBUG_ERROR(format, ...) do {} while (0)
35#define DEBUG_FATAL(format, ...) printk(format, ##__VA_ARGS__)
36
37struct octeon_hcd {
771378bb
AK
38 spinlock_t lock;
39 cvmx_usb_state_t usb;
40 struct tasklet_struct dequeue_tasklet;
41 struct list_head dequeue_list;
b164935b
AK
42};
43
44/* convert between an HCD pointer and the corresponding struct octeon_hcd */
45static inline struct octeon_hcd *hcd_to_octeon(struct usb_hcd *hcd)
46{
47 return (struct octeon_hcd *)(hcd->hcd_priv);
48}
49
50static inline struct usb_hcd *octeon_to_hcd(struct octeon_hcd *p)
51{
52 return container_of((void *)p, struct usb_hcd, hcd_priv);
53}
54
55static inline struct octeon_hcd *cvmx_usb_to_octeon(cvmx_usb_state_t *p)
56{
57 return container_of(p, struct octeon_hcd, usb);
58}
59
60static irqreturn_t octeon_usb_irq(struct usb_hcd *hcd)
61{
771378bb
AK
62 struct octeon_hcd *priv = hcd_to_octeon(hcd);
63 unsigned long flags;
64 DEBUG_CALL("OcteonUSB: %s called\n", __FUNCTION__);
65 spin_lock_irqsave(&priv->lock, flags);
66 cvmx_usb_poll(&priv->usb);
67 spin_unlock_irqrestore(&priv->lock, flags);
68 return IRQ_HANDLED;
b164935b
AK
69}
70
71static void octeon_usb_port_callback(cvmx_usb_state_t *usb,
771378bb
AK
72 cvmx_usb_callback_t reason,
73 cvmx_usb_complete_t status,
74 int pipe_handle,
75 int submit_handle,
76 int bytes_transferred,
77 void *user_data)
b164935b 78{
771378bb
AK
79 struct octeon_hcd *priv = cvmx_usb_to_octeon(usb);
80 DEBUG_CALL("OcteonUSB: %s called\n", __FUNCTION__);
81 spin_unlock(&priv->lock);
82 usb_hcd_poll_rh_status(octeon_to_hcd(priv));
83 spin_lock(&priv->lock);
b164935b
AK
84}
85
86static int octeon_usb_start(struct usb_hcd *hcd)
87{
771378bb
AK
88 struct octeon_hcd *priv = hcd_to_octeon(hcd);
89 unsigned long flags;
90 DEBUG_CALL("OcteonUSB: %s called\n", __FUNCTION__);
91 hcd->state = HC_STATE_RUNNING;
92 spin_lock_irqsave(&priv->lock, flags);
93 cvmx_usb_register_callback(&priv->usb, CVMX_USB_CALLBACK_PORT_CHANGED,
94 octeon_usb_port_callback, NULL);
95 spin_unlock_irqrestore(&priv->lock, flags);
96 return 0;
b164935b
AK
97}
98
99static void octeon_usb_stop(struct usb_hcd *hcd)
100{
771378bb
AK
101 struct octeon_hcd *priv = hcd_to_octeon(hcd);
102 unsigned long flags;
103 DEBUG_CALL("OcteonUSB: %s called\n", __FUNCTION__);
104 spin_lock_irqsave(&priv->lock, flags);
105 cvmx_usb_register_callback(&priv->usb, CVMX_USB_CALLBACK_PORT_CHANGED,
106 NULL, NULL);
107 spin_unlock_irqrestore(&priv->lock, flags);
108 hcd->state = HC_STATE_HALT;
b164935b
AK
109}
110
111static int octeon_usb_get_frame_number(struct usb_hcd *hcd)
112{
771378bb
AK
113 struct octeon_hcd *priv = hcd_to_octeon(hcd);
114 DEBUG_CALL("OcteonUSB: %s called\n", __FUNCTION__);
115 return cvmx_usb_get_frame_number(&priv->usb);
b164935b
AK
116}
117
118static void octeon_usb_urb_complete_callback(cvmx_usb_state_t *usb,
771378bb
AK
119 cvmx_usb_callback_t reason,
120 cvmx_usb_complete_t status,
121 int pipe_handle,
122 int submit_handle,
123 int bytes_transferred,
124 void *user_data)
b164935b 125{
771378bb
AK
126 struct octeon_hcd *priv = cvmx_usb_to_octeon(usb);
127 struct urb *urb = user_data;
128 DEBUG_CALL("OcteonUSB: %s called\n", __FUNCTION__);
129 urb->actual_length = bytes_transferred;
130 urb->hcpriv = NULL;
b164935b
AK
131
132 if (!list_empty(&urb->urb_list)) {
133 /*
134 * It is on the dequeue_list, but we are going to call
135 * usb_hcd_giveback_urb(), so we must clear it from
136 * the list. We got to it before the
137 * octeon_usb_urb_dequeue_work() tasklet did.
138 */
139 list_del(&urb->urb_list);
140 /* No longer on the dequeue_list. */
141 INIT_LIST_HEAD(&urb->urb_list);
142 }
143
771378bb
AK
144 /* For Isochronous transactions we need to update the URB packet status
145 list from data in our private copy */
146 if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
147 int i;
148 /* The pointer to the private list is stored in the setup_packet field */
149 cvmx_usb_iso_packet_t *iso_packet = (cvmx_usb_iso_packet_t *) urb->setup_packet;
150 /* Recalculate the transfer size by adding up each packet */
151 urb->actual_length = 0;
152 for (i = 0; i < urb->number_of_packets; i++) {
153 if (iso_packet[i].status == CVMX_USB_COMPLETE_SUCCESS) {
154 urb->iso_frame_desc[i].status = 0;
155 urb->iso_frame_desc[i].actual_length = iso_packet[i].length;
156 urb->actual_length += urb->iso_frame_desc[i].actual_length;
157 } else {
158 DEBUG_ERROR("%s: ISOCHRONOUS packet=%d of %d status=%d pipe=%d submit=%d size=%d\n",
159 __FUNCTION__, i, urb->number_of_packets,
160 iso_packet[i].status, pipe_handle,
161 submit_handle, iso_packet[i].length);
162 urb->iso_frame_desc[i].status = -EREMOTEIO;
163 }
164 }
165 /* Free the private list now that we don't need it anymore */
166 kfree(iso_packet);
167 urb->setup_packet = NULL;
168 }
169
170 switch (status) {
171 case CVMX_USB_COMPLETE_SUCCESS:
172 urb->status = 0;
173 break;
174 case CVMX_USB_COMPLETE_CANCEL:
175 if (urb->status == 0)
176 urb->status = -ENOENT;
177 break;
178 case CVMX_USB_COMPLETE_STALL:
179 DEBUG_ERROR("%s: status=stall pipe=%d submit=%d size=%d\n", __FUNCTION__, pipe_handle, submit_handle, bytes_transferred);
180 urb->status = -EPIPE;
181 break;
182 case CVMX_USB_COMPLETE_BABBLEERR:
183 DEBUG_ERROR("%s: status=babble pipe=%d submit=%d size=%d\n", __FUNCTION__, pipe_handle, submit_handle, bytes_transferred);
184 urb->status = -EPIPE;
185 break;
186 case CVMX_USB_COMPLETE_SHORT:
187 DEBUG_ERROR("%s: status=short pipe=%d submit=%d size=%d\n", __FUNCTION__, pipe_handle, submit_handle, bytes_transferred);
188 urb->status = -EREMOTEIO;
189 break;
190 case CVMX_USB_COMPLETE_ERROR:
191 case CVMX_USB_COMPLETE_XACTERR:
192 case CVMX_USB_COMPLETE_DATATGLERR:
193 case CVMX_USB_COMPLETE_FRAMEERR:
194 DEBUG_ERROR("%s: status=%d pipe=%d submit=%d size=%d\n", __FUNCTION__, status, pipe_handle, submit_handle, bytes_transferred);
195 urb->status = -EPROTO;
196 break;
197 }
198 spin_unlock(&priv->lock);
199 usb_hcd_giveback_urb(octeon_to_hcd(priv), urb, urb->status);
200 spin_lock(&priv->lock);
b164935b
AK
201}
202
203static int octeon_usb_urb_enqueue(struct usb_hcd *hcd,
771378bb
AK
204 struct urb *urb,
205 gfp_t mem_flags)
b164935b 206{
771378bb
AK
207 struct octeon_hcd *priv = hcd_to_octeon(hcd);
208 int submit_handle = -1;
209 int pipe_handle;
210 unsigned long flags;
211 cvmx_usb_iso_packet_t *iso_packet;
212 struct usb_host_endpoint *ep = urb->ep;
213
214 DEBUG_CALL("OcteonUSB: %s called\n", __FUNCTION__);
215
216 urb->status = 0;
217 INIT_LIST_HEAD(&urb->urb_list); /* not enqueued on dequeue_list */
218 spin_lock_irqsave(&priv->lock, flags);
219
220 if (!ep->hcpriv) {
221 cvmx_usb_transfer_t transfer_type;
222 cvmx_usb_speed_t speed;
223 int split_device = 0;
224 int split_port = 0;
225 switch (usb_pipetype(urb->pipe)) {
226 case PIPE_ISOCHRONOUS:
227 transfer_type = CVMX_USB_TRANSFER_ISOCHRONOUS;
228 break;
229 case PIPE_INTERRUPT:
230 transfer_type = CVMX_USB_TRANSFER_INTERRUPT;
231 break;
232 case PIPE_CONTROL:
233 transfer_type = CVMX_USB_TRANSFER_CONTROL;
234 break;
235 default:
236 transfer_type = CVMX_USB_TRANSFER_BULK;
237 break;
238 }
239 switch (urb->dev->speed) {
240 case USB_SPEED_LOW:
241 speed = CVMX_USB_SPEED_LOW;
242 break;
243 case USB_SPEED_FULL:
244 speed = CVMX_USB_SPEED_FULL;
245 break;
246 default:
247 speed = CVMX_USB_SPEED_HIGH;
248 break;
249 }
250 /* For slow devices on high speed ports we need to find the hub that
251 does the speed translation so we know where to send the split
252 transactions */
253 if (speed != CVMX_USB_SPEED_HIGH) {
254 /* Start at this device and work our way up the usb tree */
255 struct usb_device *dev = urb->dev;
256 while (dev->parent) {
257 /* If our parent is high speed then he'll receive the splits */
258 if (dev->parent->speed == USB_SPEED_HIGH) {
259 split_device = dev->parent->devnum;
260 split_port = dev->portnum;
261 break;
262 }
263 /* Move up the tree one level. If we make it all the way up the
264 tree, then the port must not be in high speed mode and we
265 don't need a split */
266 dev = dev->parent;
267 }
268 }
269 pipe_handle = cvmx_usb_open_pipe(&priv->usb,
270 0,
271 usb_pipedevice(urb->pipe),
272 usb_pipeendpoint(urb->pipe),
273 speed,
274 le16_to_cpu(ep->desc.wMaxPacketSize) & 0x7ff,
275 transfer_type,
276 usb_pipein(urb->pipe) ? CVMX_USB_DIRECTION_IN : CVMX_USB_DIRECTION_OUT,
277 urb->interval,
278 (le16_to_cpu(ep->desc.wMaxPacketSize) >> 11) & 0x3,
279 split_device,
280 split_port);
281 if (pipe_handle < 0) {
282 spin_unlock_irqrestore(&priv->lock, flags);
283 DEBUG_ERROR("OcteonUSB: %s failed to create pipe\n", __FUNCTION__);
284 return -ENOMEM;
285 }
286 ep->hcpriv = (void *)(0x10000L + pipe_handle);
c7609eac 287 } else {
771378bb 288 pipe_handle = 0xffff & (long)ep->hcpriv;
c7609eac 289 }
771378bb
AK
290
291 switch (usb_pipetype(urb->pipe)) {
292 case PIPE_ISOCHRONOUS:
293 DEBUG_SUBMIT("OcteonUSB: %s submit isochronous to %d.%d\n", __FUNCTION__, usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe));
294 /* Allocate a structure to use for our private list of isochronous
295 packets */
296 iso_packet = kmalloc(urb->number_of_packets * sizeof(cvmx_usb_iso_packet_t), GFP_ATOMIC);
297 if (iso_packet) {
298 int i;
299 /* Fill the list with the data from the URB */
300 for (i = 0; i < urb->number_of_packets; i++) {
301 iso_packet[i].offset = urb->iso_frame_desc[i].offset;
302 iso_packet[i].length = urb->iso_frame_desc[i].length;
303 iso_packet[i].status = CVMX_USB_COMPLETE_ERROR;
304 }
305 /* Store a pointer to the list in uthe URB setup_pakcet field.
306 We know this currently isn't being used and this saves us
307 a bunch of logic */
308 urb->setup_packet = (char *)iso_packet;
309 submit_handle = cvmx_usb_submit_isochronous(&priv->usb, pipe_handle,
310 urb->start_frame,
311 0 /* flags */ ,
312 urb->number_of_packets,
313 iso_packet,
314 urb->transfer_dma,
315 urb->transfer_buffer_length,
316 octeon_usb_urb_complete_callback,
317 urb);
318 /* If submit failed we need to free our private packet list */
319 if (submit_handle < 0) {
320 urb->setup_packet = NULL;
321 kfree(iso_packet);
322 }
323 }
324 break;
325 case PIPE_INTERRUPT:
326 DEBUG_SUBMIT("OcteonUSB: %s submit interrupt to %d.%d\n", __FUNCTION__, usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe));
327 submit_handle = cvmx_usb_submit_interrupt(&priv->usb, pipe_handle,
328 urb->transfer_dma,
329 urb->transfer_buffer_length,
330 octeon_usb_urb_complete_callback,
331 urb);
332 break;
333 case PIPE_CONTROL:
334 DEBUG_SUBMIT("OcteonUSB: %s submit control to %d.%d\n", __FUNCTION__, usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe));
335 submit_handle = cvmx_usb_submit_control(&priv->usb, pipe_handle,
336 urb->setup_dma,
337 urb->transfer_dma,
338 urb->transfer_buffer_length,
339 octeon_usb_urb_complete_callback,
340 urb);
341 break;
342 case PIPE_BULK:
343 DEBUG_SUBMIT("OcteonUSB: %s submit bulk to %d.%d\n", __FUNCTION__, usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe));
344 submit_handle = cvmx_usb_submit_bulk(&priv->usb, pipe_handle,
345 urb->transfer_dma,
346 urb->transfer_buffer_length,
347 octeon_usb_urb_complete_callback,
348 urb);
349 break;
350 }
351 if (submit_handle < 0) {
352 spin_unlock_irqrestore(&priv->lock, flags);
353 DEBUG_ERROR("OcteonUSB: %s failed to submit\n", __FUNCTION__);
354 return -ENOMEM;
355 }
356 urb->hcpriv = (void *)(long)(((submit_handle & 0xffff) << 16) | pipe_handle);
357 spin_unlock_irqrestore(&priv->lock, flags);
358 return 0;
b164935b
AK
359}
360
361static void octeon_usb_urb_dequeue_work(unsigned long arg)
362{
771378bb
AK
363 unsigned long flags;
364 struct octeon_hcd *priv = (struct octeon_hcd *)arg;
365
366 spin_lock_irqsave(&priv->lock, flags);
367
368 while (!list_empty(&priv->dequeue_list)) {
369 int pipe_handle;
370 int submit_handle;
371 struct urb *urb = container_of(priv->dequeue_list.next, struct urb, urb_list);
372 list_del(&urb->urb_list);
373 /* not enqueued on dequeue_list */
374 INIT_LIST_HEAD(&urb->urb_list);
375 pipe_handle = 0xffff & (long)urb->hcpriv;
376 submit_handle = ((long)urb->hcpriv) >> 16;
377 cvmx_usb_cancel(&priv->usb, pipe_handle, submit_handle);
378 }
379
380 spin_unlock_irqrestore(&priv->lock, flags);
b164935b
AK
381}
382
383static int octeon_usb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
384{
771378bb
AK
385 struct octeon_hcd *priv = hcd_to_octeon(hcd);
386 unsigned long flags;
b164935b 387
771378bb 388 DEBUG_CALL("OcteonUSB: %s called\n", __FUNCTION__);
b164935b 389
771378bb
AK
390 if (!urb->dev)
391 return -EINVAL;
b164935b 392
771378bb 393 spin_lock_irqsave(&priv->lock, flags);
b164935b 394
771378bb
AK
395 urb->status = status;
396 list_add_tail(&urb->urb_list, &priv->dequeue_list);
b164935b 397
771378bb 398 spin_unlock_irqrestore(&priv->lock, flags);
b164935b 399
771378bb 400 tasklet_schedule(&priv->dequeue_tasklet);
b164935b 401
771378bb 402 return 0;
b164935b
AK
403}
404
405static void octeon_usb_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
406{
771378bb
AK
407 DEBUG_CALL("OcteonUSB: %s called\n", __FUNCTION__);
408 if (ep->hcpriv) {
409 struct octeon_hcd *priv = hcd_to_octeon(hcd);
410 int pipe_handle = 0xffff & (long)ep->hcpriv;
411 unsigned long flags;
412 spin_lock_irqsave(&priv->lock, flags);
413 cvmx_usb_cancel_all(&priv->usb, pipe_handle);
414 if (cvmx_usb_close_pipe(&priv->usb, pipe_handle))
415 DEBUG_ERROR("OcteonUSB: Closing pipe %d failed\n", pipe_handle);
416 spin_unlock_irqrestore(&priv->lock, flags);
417 ep->hcpriv = NULL;
418 }
b164935b
AK
419}
420
421static int octeon_usb_hub_status_data(struct usb_hcd *hcd, char *buf)
422{
771378bb
AK
423 struct octeon_hcd *priv = hcd_to_octeon(hcd);
424 cvmx_usb_port_status_t port_status;
425 unsigned long flags;
b164935b 426
771378bb 427 DEBUG_CALL("OcteonUSB: %s called\n", __FUNCTION__);
b164935b 428
771378bb
AK
429 spin_lock_irqsave(&priv->lock, flags);
430 port_status = cvmx_usb_get_status(&priv->usb);
431 spin_unlock_irqrestore(&priv->lock, flags);
432 buf[0] = 0;
433 buf[0] = port_status.connect_change << 1;
b164935b 434
771378bb 435 return (buf[0] != 0);
b164935b
AK
436}
437
438static int octeon_usb_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength)
439{
771378bb
AK
440 struct octeon_hcd *priv = hcd_to_octeon(hcd);
441 cvmx_usb_port_status_t usb_port_status;
442 int port_status;
443 struct usb_hub_descriptor *desc;
444 unsigned long flags;
445
446 switch (typeReq) {
447 case ClearHubFeature:
448 DEBUG_ROOT_HUB("OcteonUSB: ClearHubFeature\n");
449 switch (wValue) {
450 case C_HUB_LOCAL_POWER:
451 case C_HUB_OVER_CURRENT:
452 /* Nothing required here */
453 break;
454 default:
455 return -EINVAL;
456 }
457 break;
458 case ClearPortFeature:
459 DEBUG_ROOT_HUB("OcteonUSB: ClearPortFeature");
460 if (wIndex != 1) {
461 DEBUG_ROOT_HUB(" INVALID\n");
462 return -EINVAL;
463 }
464
465 switch (wValue) {
466 case USB_PORT_FEAT_ENABLE:
467 DEBUG_ROOT_HUB(" ENABLE");
468 spin_lock_irqsave(&priv->lock, flags);
469 cvmx_usb_disable(&priv->usb);
470 spin_unlock_irqrestore(&priv->lock, flags);
471 break;
472 case USB_PORT_FEAT_SUSPEND:
473 DEBUG_ROOT_HUB(" SUSPEND");
474 /* Not supported on Octeon */
475 break;
476 case USB_PORT_FEAT_POWER:
477 DEBUG_ROOT_HUB(" POWER");
478 /* Not supported on Octeon */
479 break;
480 case USB_PORT_FEAT_INDICATOR:
481 DEBUG_ROOT_HUB(" INDICATOR");
482 /* Port inidicator not supported */
483 break;
484 case USB_PORT_FEAT_C_CONNECTION:
485 DEBUG_ROOT_HUB(" C_CONNECTION");
486 /* Clears drivers internal connect status change flag */
487 spin_lock_irqsave(&priv->lock, flags);
488 cvmx_usb_set_status(&priv->usb, cvmx_usb_get_status(&priv->usb));
489 spin_unlock_irqrestore(&priv->lock, flags);
490 break;
491 case USB_PORT_FEAT_C_RESET:
492 DEBUG_ROOT_HUB(" C_RESET");
493 /* Clears the driver's internal Port Reset Change flag */
494 spin_lock_irqsave(&priv->lock, flags);
495 cvmx_usb_set_status(&priv->usb, cvmx_usb_get_status(&priv->usb));
496 spin_unlock_irqrestore(&priv->lock, flags);
497 break;
498 case USB_PORT_FEAT_C_ENABLE:
499 DEBUG_ROOT_HUB(" C_ENABLE");
500 /* Clears the driver's internal Port Enable/Disable Change flag */
501 spin_lock_irqsave(&priv->lock, flags);
502 cvmx_usb_set_status(&priv->usb, cvmx_usb_get_status(&priv->usb));
503 spin_unlock_irqrestore(&priv->lock, flags);
504 break;
505 case USB_PORT_FEAT_C_SUSPEND:
506 DEBUG_ROOT_HUB(" C_SUSPEND");
507 /* Clears the driver's internal Port Suspend Change flag,
508 which is set when resume signaling on the host port is
509 complete */
510 break;
511 case USB_PORT_FEAT_C_OVER_CURRENT:
512 DEBUG_ROOT_HUB(" C_OVER_CURRENT");
513 /* Clears the driver's overcurrent Change flag */
514 spin_lock_irqsave(&priv->lock, flags);
515 cvmx_usb_set_status(&priv->usb, cvmx_usb_get_status(&priv->usb));
516 spin_unlock_irqrestore(&priv->lock, flags);
517 break;
518 default:
519 DEBUG_ROOT_HUB(" UNKNOWN\n");
520 return -EINVAL;
521 }
522 DEBUG_ROOT_HUB("\n");
523 break;
524 case GetHubDescriptor:
525 DEBUG_ROOT_HUB("OcteonUSB: GetHubDescriptor\n");
526 desc = (struct usb_hub_descriptor *)buf;
527 desc->bDescLength = 9;
528 desc->bDescriptorType = 0x29;
529 desc->bNbrPorts = 1;
530 desc->wHubCharacteristics = 0x08;
531 desc->bPwrOn2PwrGood = 1;
532 desc->bHubContrCurrent = 0;
533 desc->u.hs.DeviceRemovable[0] = 0;
534 desc->u.hs.DeviceRemovable[1] = 0xff;
535 break;
536 case GetHubStatus:
537 DEBUG_ROOT_HUB("OcteonUSB: GetHubStatus\n");
538 *(__le32 *) buf = 0;
539 break;
540 case GetPortStatus:
541 DEBUG_ROOT_HUB("OcteonUSB: GetPortStatus");
542 if (wIndex != 1) {
543 DEBUG_ROOT_HUB(" INVALID\n");
544 return -EINVAL;
545 }
546
547 spin_lock_irqsave(&priv->lock, flags);
548 usb_port_status = cvmx_usb_get_status(&priv->usb);
549 spin_unlock_irqrestore(&priv->lock, flags);
550 port_status = 0;
551
552 if (usb_port_status.connect_change) {
553 port_status |= (1 << USB_PORT_FEAT_C_CONNECTION);
554 DEBUG_ROOT_HUB(" C_CONNECTION");
555 }
556
557 if (usb_port_status.port_enabled) {
558 port_status |= (1 << USB_PORT_FEAT_C_ENABLE);
559 DEBUG_ROOT_HUB(" C_ENABLE");
560 }
561
562 if (usb_port_status.connected) {
563 port_status |= (1 << USB_PORT_FEAT_CONNECTION);
564 DEBUG_ROOT_HUB(" CONNECTION");
565 }
566
567 if (usb_port_status.port_enabled) {
568 port_status |= (1 << USB_PORT_FEAT_ENABLE);
569 DEBUG_ROOT_HUB(" ENABLE");
570 }
571
572 if (usb_port_status.port_over_current) {
573 port_status |= (1 << USB_PORT_FEAT_OVER_CURRENT);
574 DEBUG_ROOT_HUB(" OVER_CURRENT");
575 }
576
577 if (usb_port_status.port_powered) {
578 port_status |= (1 << USB_PORT_FEAT_POWER);
579 DEBUG_ROOT_HUB(" POWER");
580 }
581
582 if (usb_port_status.port_speed == CVMX_USB_SPEED_HIGH) {
583 port_status |= USB_PORT_STAT_HIGH_SPEED;
584 DEBUG_ROOT_HUB(" HIGHSPEED");
585 } else if (usb_port_status.port_speed == CVMX_USB_SPEED_LOW) {
586 port_status |= (1 << USB_PORT_FEAT_LOWSPEED);
587 DEBUG_ROOT_HUB(" LOWSPEED");
588 }
589
590 *((__le32 *) buf) = cpu_to_le32(port_status);
591 DEBUG_ROOT_HUB("\n");
592 break;
593 case SetHubFeature:
594 DEBUG_ROOT_HUB("OcteonUSB: SetHubFeature\n");
595 /* No HUB features supported */
596 break;
597 case SetPortFeature:
598 DEBUG_ROOT_HUB("OcteonUSB: SetPortFeature");
599 if (wIndex != 1) {
600 DEBUG_ROOT_HUB(" INVALID\n");
601 return -EINVAL;
602 }
603
604 switch (wValue) {
605 case USB_PORT_FEAT_SUSPEND:
606 DEBUG_ROOT_HUB(" SUSPEND\n");
607 return -EINVAL;
608 case USB_PORT_FEAT_POWER:
609 DEBUG_ROOT_HUB(" POWER\n");
610 return -EINVAL;
611 case USB_PORT_FEAT_RESET:
612 DEBUG_ROOT_HUB(" RESET\n");
613 spin_lock_irqsave(&priv->lock, flags);
614 cvmx_usb_disable(&priv->usb);
615 if (cvmx_usb_enable(&priv->usb))
616 DEBUG_ERROR("Failed to enable the port\n");
617 spin_unlock_irqrestore(&priv->lock, flags);
618 return 0;
619 case USB_PORT_FEAT_INDICATOR:
620 DEBUG_ROOT_HUB(" INDICATOR\n");
621 /* Not supported */
622 break;
623 default:
624 DEBUG_ROOT_HUB(" UNKNOWN\n");
625 return -EINVAL;
626 }
627 break;
628 default:
629 DEBUG_ROOT_HUB("OcteonUSB: Unknown root hub request\n");
630 return -EINVAL;
631 }
632 return 0;
b164935b
AK
633}
634
635
636static const struct hc_driver octeon_hc_driver = {
771378bb
AK
637 .description = "Octeon USB",
638 .product_desc = "Octeon Host Controller",
639 .hcd_priv_size = sizeof(struct octeon_hcd),
640 .irq = octeon_usb_irq,
641 .flags = HCD_MEMORY | HCD_USB2,
642 .start = octeon_usb_start,
643 .stop = octeon_usb_stop,
644 .urb_enqueue = octeon_usb_urb_enqueue,
645 .urb_dequeue = octeon_usb_urb_dequeue,
646 .endpoint_disable = octeon_usb_endpoint_disable,
647 .get_frame_number = octeon_usb_get_frame_number,
648 .hub_status_data = octeon_usb_hub_status_data,
649 .hub_control = octeon_usb_hub_control,
b164935b
AK
650};
651
652
653static int octeon_usb_driver_probe(struct device *dev)
654{
771378bb
AK
655 int status;
656 int usb_num = to_platform_device(dev)->id;
657 int irq = platform_get_irq(to_platform_device(dev), 0);
658 struct octeon_hcd *priv;
659 struct usb_hcd *hcd;
660 unsigned long flags;
661
662 DEBUG_CALL("OcteonUSB: %s called\n", __FUNCTION__);
663
664 /* Set the DMA mask to 64bits so we get buffers already translated for
665 DMA */
666 dev->coherent_dma_mask = ~0;
667 dev->dma_mask = &dev->coherent_dma_mask;
668
669 hcd = usb_create_hcd(&octeon_hc_driver, dev, dev_name(dev));
670 if (!hcd) {
671 DEBUG_FATAL("OcteonUSB: Failed to allocate memory for HCD\n");
672 return -1;
673 }
674 hcd->uses_new_polling = 1;
675 priv = (struct octeon_hcd *)hcd->hcd_priv;
676
677 spin_lock_init(&priv->lock);
678
679 tasklet_init(&priv->dequeue_tasklet, octeon_usb_urb_dequeue_work, (unsigned long)priv);
680 INIT_LIST_HEAD(&priv->dequeue_list);
681
682 //status = cvmx_usb_initialize(&priv->usb, usb_num, CVMX_USB_INITIALIZE_FLAGS_CLOCK_AUTO | CVMX_USB_INITIALIZE_FLAGS_DEBUG_INFO | CVMX_USB_INITIALIZE_FLAGS_DEBUG_TRANSFERS | CVMX_USB_INITIALIZE_FLAGS_DEBUG_CALLBACKS);
683 status = cvmx_usb_initialize(&priv->usb, usb_num, CVMX_USB_INITIALIZE_FLAGS_CLOCK_AUTO);
684 if (status) {
685 DEBUG_FATAL("OcteonUSB: USB initialization failed with %d\n", status);
686 kfree(hcd);
687 return -1;
688 }
689
690 /* This delay is needed for CN3010, but I don't know why... */
691 mdelay(10);
692
693 spin_lock_irqsave(&priv->lock, flags);
694 cvmx_usb_poll(&priv->usb);
695 spin_unlock_irqrestore(&priv->lock, flags);
696
697 status = usb_add_hcd(hcd, irq, IRQF_SHARED);
698 if (status) {
699 DEBUG_FATAL("OcteonUSB: USB add HCD failed with %d\n", status);
700 kfree(hcd);
701 return -1;
702 }
703
704 printk("OcteonUSB: Registered HCD for port %d on irq %d\n", usb_num, irq);
705
706 return 0;
b164935b
AK
707}
708
709static int octeon_usb_driver_remove(struct device *dev)
710{
771378bb
AK
711 int status;
712 struct usb_hcd *hcd = dev_get_drvdata(dev);
713 struct octeon_hcd *priv = hcd_to_octeon(hcd);
714 unsigned long flags;
b164935b 715
771378bb 716 DEBUG_CALL("OcteonUSB: %s called\n", __FUNCTION__);
b164935b 717
771378bb
AK
718 usb_remove_hcd(hcd);
719 tasklet_kill(&priv->dequeue_tasklet);
720 spin_lock_irqsave(&priv->lock, flags);
721 status = cvmx_usb_shutdown(&priv->usb);
722 spin_unlock_irqrestore(&priv->lock, flags);
723 if (status)
724 DEBUG_FATAL("OcteonUSB: USB shutdown failed with %d\n", status);
b164935b 725
771378bb 726 kfree(hcd);
b164935b 727
771378bb 728 return 0;
b164935b
AK
729}
730
731static struct device_driver octeon_usb_driver = {
771378bb
AK
732 .name = "OcteonUSB",
733 .bus = &platform_bus_type,
734 .probe = octeon_usb_driver_probe,
735 .remove = octeon_usb_driver_remove,
b164935b
AK
736};
737
738
739#define MAX_USB_PORTS 10
f5ed3a38 740static struct platform_device *pdev_glob[MAX_USB_PORTS];
b164935b
AK
741static int octeon_usb_registered;
742static int __init octeon_usb_module_init(void)
743{
771378bb
AK
744 int num_devices = cvmx_usb_get_num_ports();
745 int device;
b164935b 746
771378bb
AK
747 if (usb_disabled() || num_devices == 0)
748 return -ENODEV;
b164935b 749
771378bb
AK
750 if (driver_register(&octeon_usb_driver)) {
751 DEBUG_FATAL("OcteonUSB: Failed to register driver\n");
752 return -ENOMEM;
753 }
754 octeon_usb_registered = 1;
755 printk("OcteonUSB: Detected %d ports\n", num_devices);
b164935b
AK
756
757 /*
758 * Only cn52XX and cn56XX have DWC_OTG USB hardware and the
759 * IOB priority registers. Under heavy network load USB
760 * hardware can be starved by the IOB causing a crash. Give
761 * it a priority boost if it has been waiting more than 400
762 * cycles to avoid this situation.
763 *
764 * Testing indicates that a cnt_val of 8192 is not sufficient,
765 * but no failures are seen with 4096. We choose a value of
766 * 400 to give a safety factor of 10.
767 */
768 if (OCTEON_IS_MODEL(OCTEON_CN52XX) || OCTEON_IS_MODEL(OCTEON_CN56XX)) {
769 union cvmx_iob_n2c_l2c_pri_cnt pri_cnt;
770
771 pri_cnt.u64 = 0;
772 pri_cnt.s.cnt_enb = 1;
773 pri_cnt.s.cnt_val = 400;
774 cvmx_write_csr(CVMX_IOB_N2C_L2C_PRI_CNT, pri_cnt.u64);
775 }
776
771378bb
AK
777 for (device = 0; device < num_devices; device++) {
778 struct resource irq_resource;
779 struct platform_device *pdev;
780 memset(&irq_resource, 0, sizeof(irq_resource));
781 irq_resource.start = (device == 0) ? OCTEON_IRQ_USB0 : OCTEON_IRQ_USB1;
782 irq_resource.end = irq_resource.start;
783 irq_resource.flags = IORESOURCE_IRQ;
784 pdev = platform_device_register_simple((char *)octeon_usb_driver. name, device, &irq_resource, 1);
785 if (IS_ERR(pdev)) {
786 DEBUG_FATAL("OcteonUSB: Failed to allocate platform device for USB%d\n", device);
787 driver_unregister(&octeon_usb_driver);
788 octeon_usb_registered = 0;
789 return PTR_ERR(pdev);
790 }
791 if (device < MAX_USB_PORTS)
792 pdev_glob[device] = pdev;
793
794 }
795 return 0;
b164935b
AK
796}
797
798static void __exit octeon_usb_module_cleanup(void)
799{
771378bb
AK
800 int i;
801 DEBUG_CALL("OcteonUSB: %s called\n", __FUNCTION__);
802 for (i = 0; i < MAX_USB_PORTS; i++)
803 if (pdev_glob[i]) {
804 platform_device_unregister(pdev_glob[i]);
805 pdev_glob[i] = NULL;
806 }
b164935b
AK
807 if (octeon_usb_registered)
808 driver_unregister(&octeon_usb_driver);
809}
810
811MODULE_LICENSE("GPL");
812MODULE_AUTHOR("Cavium Networks <support@caviumnetworks.com>");
813MODULE_DESCRIPTION("Cavium Networks Octeon USB Host driver.");
814module_init(octeon_usb_module_init);
815module_exit(octeon_usb_module_cleanup);
This page took 0.06583 seconds and 5 git commands to generate.