2 * Freescale QUICC Engine USB Host Controller Driver
4 * Copyright (c) Freescale Semicondutor, Inc. 2006.
5 * Shlomi Gridish <gridish@freescale.com>
6 * Jerry Huang <Chang-Ming.Huang@freescale.com>
7 * Copyright (c) Logic Product Development, Inc. 2007
8 * Peter Barada <peterb@logicpd.com>
9 * Copyright (c) MontaVista Software, Inc. 2008.
10 * Anton Vorontsov <avorontsov@ru.mvista.com>
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
18 #include <linux/kernel.h>
19 #include <linux/types.h>
20 #include <linux/spinlock.h>
21 #include <linux/errno.h>
22 #include <linux/list.h>
23 #include <linux/usb.h>
24 #include "../core/hcd.h"
27 /* maps the hardware error code to the USB error code */
28 static int status_to_error(u32 status
)
30 if (status
== USB_TD_OK
)
32 else if (status
& USB_TD_RX_ER_CRC
)
34 else if (status
& USB_TD_RX_ER_NONOCT
)
36 else if (status
& USB_TD_RX_ER_OVERUN
)
38 else if (status
& USB_TD_RX_ER_BITSTUFF
)
40 else if (status
& USB_TD_RX_ER_PID
)
42 else if (status
& (USB_TD_TX_ER_NAK
| USB_TD_TX_ER_TIMEOUT
))
44 else if (status
& USB_TD_TX_ER_STALL
)
46 else if (status
& USB_TD_TX_ER_UNDERUN
)
48 else if (status
& USB_TD_RX_DATA_UNDERUN
)
50 else if (status
& USB_TD_RX_DATA_OVERUN
)
56 void fhci_add_td_to_frame(struct fhci_time_frame
*frame
, struct td
*td
)
58 list_add_tail(&td
->frame_lh
, &frame
->tds_list
);
61 void fhci_add_tds_to_ed(struct ed
*ed
, struct td
**td_list
, int number
)
65 for (i
= 0; i
< number
; i
++) {
66 struct td
*td
= td_list
[i
];
67 list_add_tail(&td
->node
, &ed
->td_list
);
69 if (ed
->td_head
== NULL
)
70 ed
->td_head
= td_list
[0];
73 static struct td
*peek_td_from_ed(struct ed
*ed
)
77 if (!list_empty(&ed
->td_list
))
78 td
= list_entry(ed
->td_list
.next
, struct td
, node
);
85 struct td
*fhci_remove_td_from_frame(struct fhci_time_frame
*frame
)
89 if (!list_empty(&frame
->tds_list
)) {
90 td
= list_entry(frame
->tds_list
.next
, struct td
, frame_lh
);
91 list_del_init(frame
->tds_list
.next
);
98 struct td
*fhci_peek_td_from_frame(struct fhci_time_frame
*frame
)
102 if (!list_empty(&frame
->tds_list
))
103 td
= list_entry(frame
->tds_list
.next
, struct td
, frame_lh
);
110 struct td
*fhci_remove_td_from_ed(struct ed
*ed
)
114 if (!list_empty(&ed
->td_list
)) {
115 td
= list_entry(ed
->td_list
.next
, struct td
, node
);
116 list_del_init(ed
->td_list
.next
);
118 /* if this TD was the ED's head, find next TD */
119 if (!list_empty(&ed
->td_list
))
120 ed
->td_head
= list_entry(ed
->td_list
.next
, struct td
,
130 struct td
*fhci_remove_td_from_done_list(struct fhci_controller_list
*p_list
)
134 if (!list_empty(&p_list
->done_list
)) {
135 td
= list_entry(p_list
->done_list
.next
, struct td
, node
);
136 list_del_init(p_list
->done_list
.next
);
143 void fhci_move_td_from_ed_to_done_list(struct fhci_usb
*usb
, struct ed
*ed
)
148 list_del_init(&td
->node
);
150 /* If this TD was the ED's head,find next TD */
151 if (!list_empty(&ed
->td_list
))
152 ed
->td_head
= list_entry(ed
->td_list
.next
, struct td
, node
);
155 ed
->state
= FHCI_ED_SKIP
;
157 ed
->toggle_carry
= td
->toggle
;
158 list_add_tail(&td
->node
, &usb
->hc_list
->done_list
);
160 usb
->transfer_confirm(usb
->fhci
);
163 /* free done FHCI URB resource such as ED and TD */
164 static void free_urb_priv(struct fhci_hcd
*fhci
, struct urb
*urb
)
167 struct urb_priv
*urb_priv
= urb
->hcpriv
;
168 struct ed
*ed
= urb_priv
->ed
;
170 for (i
= 0; i
< urb_priv
->num_of_tds
; i
++) {
171 list_del_init(&urb_priv
->tds
[i
]->node
);
172 fhci_recycle_empty_td(fhci
, urb_priv
->tds
[i
]);
175 /* if this TD was the ED's head,find the next TD */
176 if (!list_empty(&ed
->td_list
))
177 ed
->td_head
= list_entry(ed
->td_list
.next
, struct td
, node
);
181 kfree(urb_priv
->tds
);
185 /* if this TD was the ED's head,find next TD */
186 if (ed
->td_head
== NULL
)
187 list_del_init(&ed
->node
);
191 /* this routine called to complete and free done URB */
192 void fhci_urb_complete_free(struct fhci_hcd
*fhci
, struct urb
*urb
)
194 free_urb_priv(fhci
, urb
);
196 if (urb
->status
== -EINPROGRESS
) {
197 if (urb
->actual_length
!= urb
->transfer_buffer_length
&&
198 urb
->transfer_flags
& URB_SHORT_NOT_OK
)
199 urb
->status
= -EREMOTEIO
;
204 usb_hcd_unlink_urb_from_ep(fhci_to_hcd(fhci
), urb
);
206 spin_unlock(&fhci
->lock
);
208 usb_hcd_giveback_urb(fhci_to_hcd(fhci
), urb
, urb
->status
);
210 spin_lock(&fhci
->lock
);
214 * caculate transfer length/stats and update the urb
215 * Precondition: irqsafe(only for urb-?status locking)
217 void fhci_done_td(struct urb
*urb
, struct td
*td
)
219 struct ed
*ed
= td
->ed
;
222 /* ISO...drivers see per-TD length/status */
223 if (ed
->mode
== FHCI_TF_ISO
) {
225 if (!(urb
->transfer_flags
& URB_SHORT_NOT_OK
&&
226 cc
== USB_TD_RX_DATA_UNDERUN
))
229 if (usb_pipeout(urb
->pipe
))
230 len
= urb
->iso_frame_desc
[td
->iso_index
].length
;
232 len
= td
->actual_len
;
234 urb
->actual_length
+= len
;
235 urb
->iso_frame_desc
[td
->iso_index
].actual_length
= len
;
236 urb
->iso_frame_desc
[td
->iso_index
].status
=
240 /* BULK,INT,CONTROL... drivers see aggregate length/status,
241 * except that "setup" bytes aren't counted and "short" transfers
242 * might not be reported as errors.
245 if (td
->error_cnt
>= 3)
246 urb
->error_count
= 3;
248 /* control endpoint only have soft stalls */
250 /* update packet status if needed(short may be ok) */
251 if (!(urb
->transfer_flags
& URB_SHORT_NOT_OK
) &&
252 cc
== USB_TD_RX_DATA_UNDERUN
) {
253 ed
->state
= FHCI_ED_OPER
;
256 if (cc
!= USB_TD_OK
) {
257 if (urb
->status
== -EINPROGRESS
)
258 urb
->status
= status_to_error(cc
);
261 /* count all non-empty packets except control SETUP packet */
262 if (td
->type
!= FHCI_TA_SETUP
|| td
->iso_index
!= 0)
263 urb
->actual_length
+= td
->actual_len
;
267 /* there are some pedning request to unlink */
268 void fhci_del_ed_list(struct fhci_hcd
*fhci
, struct ed
*ed
)
270 struct td
*td
= peek_td_from_ed(ed
);
271 struct urb
*urb
= td
->urb
;
272 struct urb_priv
*urb_priv
= urb
->hcpriv
;
274 if (urb_priv
->state
== URB_DEL
) {
275 td
= fhci_remove_td_from_ed(ed
);
276 /* HC may have partly processed this TD */
277 if (td
->status
!= USB_TD_INPROGRESS
)
278 fhci_done_td(urb
, td
);
280 /* URB is done;clean up */
281 if (++(urb_priv
->tds_cnt
) == urb_priv
->num_of_tds
)
282 fhci_urb_complete_free(fhci
, urb
);