Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
R
reform-boundary-uboot
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Jack Humbert
reform-boundary-uboot
Commits
aba637ba
Commit
aba637ba
authored
17 years ago
by
Wolfgang Denk
Browse files
Options
Downloads
Plain Diff
Merge branch 'master' of /home/wd/git/u-boot/custodians
parents
99722330
9e8362b6
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
drivers/isp116x-hcd.c
+72
-40
72 additions, 40 deletions
drivers/isp116x-hcd.c
with
72 additions
and
40 deletions
drivers/isp116x-hcd.c
+
72
−
40
View file @
aba637ba
...
@@ -113,9 +113,9 @@ static const char hcd_name[] = "isp116x-hcd";
...
@@ -113,9 +113,9 @@ static const char hcd_name[] = "isp116x-hcd";
struct
isp116x
isp116x_dev
;
struct
isp116x
isp116x_dev
;
struct
isp116x_platform_data
isp116x_board
;
struct
isp116x_platform_data
isp116x_board
;
int
got_rhsc
=
0
;
/* root hub status change */
static
int
got_rhsc
;
/* root hub status change */
struct
usb_device
*
devgone
;
/* device which was disconnected */
struct
usb_device
*
devgone
;
/* device which was disconnected */
int
rh_devnum
=
0
;
/* address of Root Hub endpoint */
static
int
rh_devnum
;
/* address of Root Hub endpoint */
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
...
@@ -522,11 +522,13 @@ static int unpack_fifo(struct isp116x *isp116x, struct usb_device *dev,
...
@@ -522,11 +522,13 @@ static int unpack_fifo(struct isp116x *isp116x, struct usb_device *dev,
done
+=
PTD_GET_LEN
(
&
ptd
[
i
]);
done
+=
PTD_GET_LEN
(
&
ptd
[
i
]);
cc
=
PTD_GET_CC
(
&
ptd
[
i
]);
cc
=
PTD_GET_CC
(
&
ptd
[
i
]);
if
(
cc
==
TD_DATAUNDERRUN
)
{
/* underrun is no error... */
DBG
(
"allowed data underrun"
);
/* Data underrun means basically that we had more buffer space than
cc
=
TD_CC_NOERROR
;
* the function had data. It is perfectly normal but upper levels have
}
* to know how much we actually transferred.
if
(
cc
!=
TD_CC_NOERROR
&&
ret
==
TD_CC_NOERROR
)
*/
if
(
cc
==
TD_NOTACCESSED
||
(
cc
!=
TD_CC_NOERROR
&&
(
ret
==
TD_CC_NOERROR
||
ret
==
TD_DATAUNDERRUN
)))
ret
=
cc
;
ret
=
cc
;
}
}
...
@@ -592,11 +594,19 @@ static int isp116x_interrupt(struct isp116x *isp116x)
...
@@ -592,11 +594,19 @@ static int isp116x_interrupt(struct isp116x *isp116x)
return
ret
;
return
ret
;
}
}
#define PTD_NUM 64
/* it should be enougth... */
/* With one PTD we can transfer almost 1K in one go;
struct
ptd
ptd
[
PTD_NUM
];
* HC does the splitting into endpoint digestible transactions
*/
struct
ptd
ptd
[
1
];
static
inline
int
max_transfer_len
(
struct
usb_device
*
dev
,
unsigned
long
pipe
)
static
inline
int
max_transfer_len
(
struct
usb_device
*
dev
,
unsigned
long
pipe
)
{
{
return
min
(
PTD_NUM
*
usb_maxpacket
(
dev
,
pipe
),
PTD_NUM
*
16
);
unsigned
mpck
=
usb_maxpacket
(
dev
,
pipe
);
/* One PTD can transfer 1023 bytes but try to always
* transfer multiples of endpoint buffer size
*/
return
1023
/
mpck
*
mpck
;
}
}
/* Do an USB transfer
/* Do an USB transfer
...
@@ -610,13 +620,21 @@ static int isp116x_submit_job(struct usb_device *dev, unsigned long pipe,
...
@@ -610,13 +620,21 @@ static int isp116x_submit_job(struct usb_device *dev, unsigned long pipe,
int
max
=
usb_maxpacket
(
dev
,
pipe
);
int
max
=
usb_maxpacket
(
dev
,
pipe
);
int
dir_out
=
usb_pipeout
(
pipe
);
int
dir_out
=
usb_pipeout
(
pipe
);
int
speed_low
=
usb_pipeslow
(
pipe
);
int
speed_low
=
usb_pipeslow
(
pipe
);
int
i
,
done
,
stat
,
timeout
,
cc
;
int
i
,
done
=
0
,
stat
,
timeout
,
cc
;
int
retries
=
10
;
/* 500 frames or 0.5s timeout when function is busy and NAKs transactions for a while */
int
retries
=
500
;
DBG
(
"------------------------------------------------"
);
DBG
(
"------------------------------------------------"
);
dump_msg
(
dev
,
pipe
,
buffer
,
len
,
"SUBMIT"
);
dump_msg
(
dev
,
pipe
,
buffer
,
len
,
"SUBMIT"
);
DBG
(
"------------------------------------------------"
);
DBG
(
"------------------------------------------------"
);
if
(
len
>=
1024
)
{
ERR
(
"Too big job"
);
dev
->
status
=
USB_ST_CRC_ERR
;
return
-
1
;
}
if
(
isp116x
->
disabled
)
{
if
(
isp116x
->
disabled
)
{
ERR
(
"EPIPE"
);
ERR
(
"EPIPE"
);
dev
->
status
=
USB_ST_CRC_ERR
;
dev
->
status
=
USB_ST_CRC_ERR
;
...
@@ -653,29 +671,15 @@ static int isp116x_submit_job(struct usb_device *dev, unsigned long pipe,
...
@@ -653,29 +671,15 @@ static int isp116x_submit_job(struct usb_device *dev, unsigned long pipe,
isp116x_write_reg32
(
isp116x
,
HCINTSTAT
,
0xff
);
isp116x_write_reg32
(
isp116x
,
HCINTSTAT
,
0xff
);
/* Prepare the PTD data */
/* Prepare the PTD data */
done
=
0
;
ptd
->
count
=
PTD_CC_MSK
|
PTD_ACTIVE_MSK
|
i
=
0
;
PTD_TOGGLE
(
usb_gettoggle
(
dev
,
epnum
,
dir_out
));
do
{
ptd
->
mps
=
PTD_MPS
(
max
)
|
PTD_SPD
(
speed_low
)
|
PTD_EP
(
epnum
)
|
PTD_LAST_MSK
;
ptd
[
i
].
count
=
PTD_CC_MSK
|
PTD_ACTIVE_MSK
|
ptd
->
len
=
PTD_LEN
(
len
)
|
PTD_DIR
(
dir
);
PTD_TOGGLE
(
usb_gettoggle
(
dev
,
epnum
,
dir_out
));
ptd
->
faddr
=
PTD_FA
(
usb_pipedevice
(
pipe
));
ptd
[
i
].
mps
=
PTD_MPS
(
max
)
|
PTD_SPD
(
speed_low
)
|
PTD_EP
(
epnum
);
ptd
[
i
].
len
=
PTD_LEN
(
max
>
len
-
done
?
len
-
done
:
max
)
|
PTD_DIR
(
dir
);
ptd
[
i
].
faddr
=
PTD_FA
(
usb_pipedevice
(
pipe
));
usb_dotoggle
(
dev
,
epnum
,
dir_out
);
done
+=
PTD_GET_LEN
(
&
ptd
[
i
]);
i
++
;
if
(
i
>=
PTD_NUM
)
{
ERR
(
"****** Cannot pack buffer! ******"
);
dev
->
status
=
USB_ST_BUF_ERR
;
return
-
1
;
}
}
while
(
done
<
len
);
ptd
[
i
-
1
].
mps
|=
PTD_LAST_MSK
;
retry_same:
/* Pack data into FIFO ram */
/* Pack data into FIFO ram */
pack_fifo
(
isp116x
,
dev
,
pipe
,
ptd
,
i
,
buffer
,
len
);
pack_fifo
(
isp116x
,
dev
,
pipe
,
ptd
,
1
,
buffer
,
len
);
#ifdef EXTRA_DELAY
#ifdef EXTRA_DELAY
wait_ms
(
EXTRA_DELAY
);
wait_ms
(
EXTRA_DELAY
);
#endif
#endif
...
@@ -738,17 +742,42 @@ static int isp116x_submit_job(struct usb_device *dev, unsigned long pipe,
...
@@ -738,17 +742,42 @@ static int isp116x_submit_job(struct usb_device *dev, unsigned long pipe,
}
}
/* Unpack data from FIFO ram */
/* Unpack data from FIFO ram */
cc
=
unpack_fifo
(
isp116x
,
dev
,
pipe
,
ptd
,
i
,
buffer
,
len
);
cc
=
unpack_fifo
(
isp116x
,
dev
,
pipe
,
ptd
,
1
,
buffer
,
len
);
i
=
PTD_GET_COUNT
(
ptd
);
done
+=
i
;
buffer
+=
i
;
len
-=
i
;
/*
Mmm... sometime we get 0x0f as cc which is a non sense!
/*
There was some kind of real problem; Prepare the PTD again
*
Just
retry
the transfer...
*
and
retry
from the failed transaction on
*/
*/
if
(
cc
==
0x0f
&&
retries
--
>
0
)
{
if
(
cc
&&
cc
!=
TD_NOTACCESSED
&&
cc
!=
TD_DATAUNDERRUN
)
{
usb_dotoggle
(
dev
,
epnum
,
dir_out
);
if
(
retries
>=
100
)
{
goto
retry
;
retries
-=
100
;
/* The chip will have toggled the toggle bit for the failed
* transaction too. We have to toggle it back.
*/
usb_settoggle
(
dev
,
epnum
,
dir_out
,
!
PTD_GET_TOGGLE
(
ptd
));
goto
retry
;
}
}
/* "Normal" errors; TD_NOTACCESSED would mean in effect that the function have NAKed
* the transactions from the first on for the whole frame. It may be busy and we retry
* with the same PTD. PTD_ACTIVE (and not TD_NOTACCESSED) would mean that some of the
* PTD didn't make it because the function was busy or the frame ended before the PTD
* finished. We prepare the rest of the data and try again.
*/
else
if
(
cc
==
TD_NOTACCESSED
||
PTD_GET_ACTIVE
(
ptd
)
||
(
cc
!=
TD_DATAUNDERRUN
&&
PTD_GET_COUNT
(
ptd
)
<
PTD_GET_LEN
(
ptd
)))
{
if
(
retries
)
{
--
retries
;
if
(
cc
==
TD_NOTACCESSED
&&
PTD_GET_ACTIVE
(
ptd
)
&&
!
PTD_GET_COUNT
(
ptd
))
goto
retry_same
;
usb_settoggle
(
dev
,
epnum
,
dir_out
,
PTD_GET_TOGGLE
(
ptd
));
goto
retry
;
}
}
}
if
(
cc
!=
TD_CC_NOERROR
)
{
if
(
cc
!=
TD_CC_NOERROR
&&
cc
!=
TD_DATAUNDERRUN
)
{
DBG
(
"****** completition code error %x ******"
,
cc
);
DBG
(
"****** completition code error %x ******"
,
cc
);
switch
(
cc
)
{
switch
(
cc
)
{
case
TD_CC_BITSTUFFING
:
case
TD_CC_BITSTUFFING
:
...
@@ -766,6 +795,7 @@ static int isp116x_submit_job(struct usb_device *dev, unsigned long pipe,
...
@@ -766,6 +795,7 @@ static int isp116x_submit_job(struct usb_device *dev, unsigned long pipe,
}
}
return
-
cc
;
return
-
cc
;
}
}
else
usb_settoggle
(
dev
,
epnum
,
dir_out
,
PTD_GET_TOGGLE
(
ptd
));
dump_msg
(
dev
,
pipe
,
buffer
,
len
,
"SUBMIT(ret)"
);
dump_msg
(
dev
,
pipe
,
buffer
,
len
,
"SUBMIT(ret)"
);
...
@@ -1369,6 +1399,8 @@ int usb_lowlevel_init(void)
...
@@ -1369,6 +1399,8 @@ int usb_lowlevel_init(void)
DBG
(
""
);
DBG
(
""
);
got_rhsc
=
rh_devnum
=
0
;
/* Init device registers addr */
/* Init device registers addr */
isp116x
->
addr_reg
=
(
u16
*
)
ISP116X_HCD_ADDR
;
isp116x
->
addr_reg
=
(
u16
*
)
ISP116X_HCD_ADDR
;
isp116x
->
data_reg
=
(
u16
*
)
ISP116X_HCD_DATA
;
isp116x
->
data_reg
=
(
u16
*
)
ISP116X_HCD_DATA
;
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment