Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
dfd47943
Commit
dfd47943
authored
Sep 15, 2002
by
Greg Kroah-Hartman
Browse files
Options
Browse Files
Download
Plain Diff
Merge kroah.com:/home/greg/linux/BK/bleeding_edge-2.5
into kroah.com:/home/greg/linux/BK/gregkh-2.5
parents
49cda8eb
bcee5ba0
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
104 additions
and
144 deletions
+104
-144
drivers/usb/storage/debug.c
drivers/usb/storage/debug.c
+1
-1
drivers/usb/storage/debug.h
drivers/usb/storage/debug.h
+1
-1
drivers/usb/storage/freecom.c
drivers/usb/storage/freecom.c
+2
-2
drivers/usb/storage/isd200.c
drivers/usb/storage/isd200.c
+18
-33
drivers/usb/storage/protocol.c
drivers/usb/storage/protocol.c
+1
-1
drivers/usb/storage/raw_bulk.c
drivers/usb/storage/raw_bulk.c
+7
-9
drivers/usb/storage/scsiglue.c
drivers/usb/storage/scsiglue.c
+9
-12
drivers/usb/storage/sddr09.c
drivers/usb/storage/sddr09.c
+16
-19
drivers/usb/storage/shuttle_usbat.c
drivers/usb/storage/shuttle_usbat.c
+6
-3
drivers/usb/storage/transport.c
drivers/usb/storage/transport.c
+38
-55
drivers/usb/storage/usb.c
drivers/usb/storage/usb.c
+3
-5
drivers/usb/storage/usb.h
drivers/usb/storage/usb.h
+2
-3
No files found.
drivers/usb/storage/debug.c
View file @
dfd47943
...
...
@@ -189,7 +189,7 @@ void usb_stor_print_Scsi_Cmnd( Scsi_Cmnd* cmd )
US_DEBUGP
(
"Buffer has %d scatterlists.
\n
"
,
cmd
->
use_sg
);
for
(
i
=
0
;
i
<
cmd
->
use_sg
;
i
++
)
{
char
*
adr
=
page_address
(
sg
[
i
].
page
)
+
sg
[
i
].
offset
;
char
*
adr
=
sg_address
(
sg
[
i
])
;
US_DEBUGP
(
"Length of scatterlist %d is %d.
\n
"
,
i
,
sg
[
i
].
length
);
US_DEBUGP
(
"%02x %02x %02x %02x %02x %02x %02x %02x
\n
"
...
...
drivers/usb/storage/debug.h
View file @
dfd47943
...
...
@@ -48,7 +48,7 @@
#include <linux/kernel.h>
#include <linux/blk.h>
#include <linux/cdrom.h>
#include "
scsi
.h"
#include "
usb
.h"
#define USB_STORAGE "usb-storage: "
...
...
drivers/usb/storage/freecom.c
View file @
dfd47943
...
...
@@ -148,11 +148,11 @@ static void us_transfer_freecom(Scsi_Cmnd *srb, struct us_data* us, int transfer
if
(
transfer_amount
-
total_transferred
>=
sg
[
i
].
length
)
{
result
=
usb_stor_transfer_partial
(
us
,
page_address
(
sg
[
i
].
page
)
+
sg
[
i
].
offset
,
sg
[
i
].
length
);
sg_address
(
sg
[
i
])
,
sg
[
i
].
length
);
total_transferred
+=
sg
[
i
].
length
;
}
else
{
result
=
usb_stor_transfer_partial
(
us
,
page_address
(
sg
[
i
].
page
)
+
sg
[
i
].
offset
,
sg_address
(
sg
[
i
])
,
transfer_amount
-
total_transferred
);
total_transferred
+=
transfer_amount
-
total_transferred
;
}
...
...
drivers/usb/storage/isd200.c
View file @
dfd47943
...
...
@@ -425,7 +425,8 @@ static int isd200_transfer_partial( struct us_data *us,
/* if we stall, we need to clear it before we go on */
if
(
result
==
-
EPIPE
)
{
US_DEBUGP
(
"clearing endpoint halt for pipe 0x%x
\n
"
,
pipe
);
usb_stor_clear_halt
(
us
,
pipe
);
if
(
usb_stor_clear_halt
(
us
,
pipe
)
<
0
)
return
ISD200_TRANSPORT_FAILED
;
}
/* did we send all the data? */
...
...
@@ -501,13 +502,13 @@ static void isd200_transfer( struct us_data *us, Scsi_Cmnd *srb )
sg
[
i
].
length
)
{
result
=
isd200_transfer_partial
(
us
,
srb
->
sc_data_direction
,
page_address
(
sg
[
i
].
page
)
+
sg
[
i
].
offset
,
sg_address
(
sg
[
i
])
,
sg
[
i
].
length
);
total_transferred
+=
sg
[
i
].
length
;
}
else
result
=
isd200_transfer_partial
(
us
,
srb
->
sc_data_direction
,
page_address
(
sg
[
i
].
page
)
+
sg
[
i
].
offset
,
sg_address
(
sg
[
i
])
,
transfer_amount
-
total_transferred
);
/* if we get an error, end the loop here */
...
...
@@ -589,7 +590,8 @@ int isd200_Bulk_transport( struct us_data *us, Scsi_Cmnd *srb,
else
if
(
result
==
-
EPIPE
)
{
/* if we stall, we need to clear it before we go on */
US_DEBUGP
(
"clearing endpoint halt for pipe 0x%x
\n
"
,
pipe
);
usb_stor_clear_halt
(
us
,
pipe
);
if
(
usb_stor_clear_halt
(
us
,
pipe
)
<
0
)
return
ISD200_TRANSPORT_ERROR
;
}
else
if
(
result
)
return
ISD200_TRANSPORT_ERROR
;
...
...
@@ -621,7 +623,8 @@ int isd200_Bulk_transport( struct us_data *us, Scsi_Cmnd *srb,
/* did the attempt to read the CSW fail? */
if
(
result
==
-
EPIPE
)
{
US_DEBUGP
(
"clearing endpoint halt for pipe 0x%x
\n
"
,
pipe
);
usb_stor_clear_halt
(
us
,
pipe
);
if
(
usb_stor_clear_halt
(
us
,
pipe
)
<
0
)
return
ISD200_TRANSPORT_ERROR
;
/* get the status again */
US_DEBUGP
(
"Attempting to get CSW (2nd try)...
\n
"
);
...
...
@@ -824,7 +827,7 @@ void isd200_invoke_transport( struct us_data *us,
case
ISD200_TRANSPORT_GOOD
:
/* Indicate a good result */
srb
->
result
=
GOOD
;
srb
->
result
=
GOOD
<<
1
;
break
;
case
ISD200_TRANSPORT_ABORTED
:
...
...
@@ -946,15 +949,6 @@ int isd200_write_config( struct us_data *us )
US_DEBUGP
(
" ISD200 Config Data was written successfully
\n
"
);
}
else
{
US_DEBUGP
(
" Request to write ISD200 Config Data failed!
\n
"
);
/* STALL must be cleared when they are detected */
if
(
result
==
-
EPIPE
)
{
US_DEBUGP
(
"-- Stall on control pipe. Clearing
\n
"
);
result
=
usb_stor_clear_halt
(
us
,
usb_sndctrlpipe
(
us
->
pusb_dev
,
0
));
US_DEBUGP
(
"-- usb_stor_clear_halt() returns %d
\n
"
,
result
);
}
retStatus
=
ISD200_ERROR
;
}
...
...
@@ -1000,15 +994,6 @@ int isd200_read_config( struct us_data *us )
#endif
}
else
{
US_DEBUGP
(
" Request to get ISD200 Config Data failed!
\n
"
);
/* STALL must be cleared when they are detected */
if
(
result
==
-
EPIPE
)
{
US_DEBUGP
(
"-- Stall on control pipe. Clearing
\n
"
);
result
=
usb_stor_clear_halt
(
us
,
usb_sndctrlpipe
(
us
->
pusb_dev
,
0
));
US_DEBUGP
(
"-- usb_stor_clear_halt() returns %d
\n
"
,
result
);
}
retStatus
=
ISD200_ERROR
;
}
...
...
@@ -1271,7 +1256,7 @@ int isd200_get_inquiry_data( struct us_data *us )
/* ATA Command Identify successful */
int
i
;
__u16
*
src
,
*
dest
;
ata
_fix_driveid
(
&
info
->
drive
);
ide
_fix_driveid
(
&
info
->
drive
);
US_DEBUGP
(
" Identify Data Structure:
\n
"
);
US_DEBUGP
(
" config = 0x%x
\n
"
,
info
->
drive
.
config
);
...
...
@@ -1409,10 +1394,10 @@ void isd200_data_copy(Scsi_Cmnd *srb, char * src, int length)
/* transfer the lesser of the next buffer or the
* remaining data */
if
(
len
-
total
>=
sg
[
i
].
length
)
{
memcpy
(
page_address
(
sg
[
i
].
page
)
+
sg
[
i
].
offset
,
src
+
total
,
sg
[
i
].
length
);
memcpy
(
sg_address
(
sg
[
i
])
,
src
+
total
,
sg
[
i
].
length
);
total
+=
sg
[
i
].
length
;
}
else
{
memcpy
(
page_address
(
sg
[
i
].
page
)
+
sg
[
i
].
offset
,
src
+
total
,
len
-
total
);
memcpy
(
sg_address
(
sg
[
i
])
,
src
+
total
,
len
-
total
);
total
=
len
;
}
}
...
...
@@ -1462,7 +1447,7 @@ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us,
/* copy InquiryData */
isd200_data_copy
(
srb
,
(
char
*
)
&
info
->
InquiryData
,
srb
->
request_bufflen
);
srb
->
result
=
GOOD
;
srb
->
result
=
GOOD
<<
1
;
sendToTransport
=
FALSE
;
break
;
...
...
@@ -1482,7 +1467,7 @@ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us,
srb
->
request_bufflen
=
0
;
}
else
{
US_DEBUGP
(
" Media Status not supported, just report okay
\n
"
);
srb
->
result
=
GOOD
;
srb
->
result
=
GOOD
<<
1
;
sendToTransport
=
FALSE
;
}
break
;
...
...
@@ -1503,7 +1488,7 @@ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us,
srb
->
request_bufflen
=
0
;
}
else
{
US_DEBUGP
(
" Media Status not supported, just report okay
\n
"
);
srb
->
result
=
GOOD
;
srb
->
result
=
GOOD
<<
1
;
sendToTransport
=
FALSE
;
}
break
;
...
...
@@ -1529,7 +1514,7 @@ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us,
srb
->
request_bufflen
=
sizeof
(
struct
read_capacity_data
);
isd200_data_copy
(
srb
,
(
char
*
)
&
readCapacityData
,
srb
->
request_bufflen
);
srb
->
result
=
GOOD
;
srb
->
result
=
GOOD
<<
1
;
sendToTransport
=
FALSE
;
}
break
;
...
...
@@ -1613,7 +1598,7 @@ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us,
srb
->
request_bufflen
=
0
;
}
else
{
US_DEBUGP
(
" Not removeable media, just report okay
\n
"
);
srb
->
result
=
GOOD
;
srb
->
result
=
GOOD
<<
1
;
sendToTransport
=
FALSE
;
}
break
;
...
...
@@ -1642,7 +1627,7 @@ int isd200_scsi_to_ata(Scsi_Cmnd *srb, struct us_data *us,
srb
->
request_bufflen
=
0
;
}
else
{
US_DEBUGP
(
" Nothing to do, just report okay
\n
"
);
srb
->
result
=
GOOD
;
srb
->
result
=
GOOD
<<
1
;
sendToTransport
=
FALSE
;
}
break
;
...
...
drivers/usb/storage/protocol.c
View file @
dfd47943
...
...
@@ -65,7 +65,7 @@ find_data_location(Scsi_Cmnd *srb) {
struct
scatterlist
*
sg
;
sg
=
(
struct
scatterlist
*
)
srb
->
request_buffer
;
return
(
void
*
)
page_address
(
sg
[
0
].
page
)
+
sg
[
0
].
offset
;
return
(
void
*
)
sg_address
(
sg
[
0
])
;
}
else
return
(
void
*
)
srb
->
request_buffer
;
}
...
...
drivers/usb/storage/raw_bulk.c
View file @
dfd47943
...
...
@@ -67,12 +67,9 @@ usb_storage_send_control(struct us_data *us,
// Check the return code for the command.
if
(
result
<
0
)
{
/* a stall i
s a fatal condition from the device
*/
/* a stall i
ndicates a protocol error
*/
if
(
result
==
-
EPIPE
)
{
US_DEBUGP
(
"-- Stall on control pipe. Clearing
\n
"
);
result
=
usb_stor_clear_halt
(
us
,
pipe
);
US_DEBUGP
(
"-- usb_stor_clear_halt() returns %d
\n
"
,
result
);
US_DEBUGP
(
"-- Stall on control pipe
\n
"
);
return
USB_STOR_TRANSPORT_FAILED
;
}
...
...
@@ -102,7 +99,8 @@ usb_storage_raw_bulk(struct us_data *us, int direction, unsigned char *data,
US_DEBUGP
(
"EPIPE: clearing endpoint halt for"
" pipe 0x%x, stalled at %d bytes
\n
"
,
pipe
,
*
act_len
);
usb_stor_clear_halt
(
us
,
pipe
);
if
(
usb_stor_clear_halt
(
us
,
pipe
)
<
0
)
return
US_BULK_TRANSFER_FAILED
;
/* return US_BULK_TRANSFER_SHORT; */
}
...
...
@@ -191,7 +189,7 @@ usb_storage_bulk_transport(struct us_data *us, int direction,
unsigned
char
*
buf
;
unsigned
int
length
;
buf
=
page_address
(
sg
[
i
].
page
)
+
sg
[
i
].
offset
;
buf
=
sg_address
(
sg
[
i
])
;
length
=
len
-
transferred
;
if
(
length
>
sg
[
i
].
length
)
length
=
sg
[
i
].
length
;
...
...
@@ -261,7 +259,7 @@ us_copy_from_sgbuf(unsigned char *content, int len,
unsigned
char
*
ptr
;
unsigned
int
length
,
room
;
ptr
=
page_address
(
sg
[
i
].
page
)
+
sg
[
i
].
offset
+
*
offset
;
ptr
=
sg_address
(
sg
[
i
])
+
*
offset
;
room
=
sg
[
i
].
length
-
*
offset
;
length
=
len
-
transferred
;
...
...
@@ -310,7 +308,7 @@ us_copy_to_sgbuf(unsigned char *buffer, int buflen,
unsigned
char
*
ptr
;
unsigned
int
length
,
room
;
ptr
=
page_address
(
sg
[
i
].
page
)
+
sg
[
i
].
offset
+
*
offset
;
ptr
=
sg_address
(
sg
[
i
])
+
*
offset
;
room
=
sg
[
i
].
length
-
*
offset
;
length
=
buflen
-
transferred
;
...
...
drivers/usb/storage/scsiglue.c
View file @
dfd47943
...
...
@@ -563,8 +563,8 @@ int usb_stor_scsiSense10to6( Scsi_Cmnd* the10 )
/* copy one byte */
{
char
*
src
=
page_address
(
sg
[
sb
].
page
)
+
sg
[
sb
].
offset
+
si
;
char
*
dst
=
page_address
(
sg
[
db
].
page
)
+
sg
[
db
].
offset
+
di
;
char
*
src
=
sg_address
(
sg
[
sb
])
+
si
;
char
*
dst
=
sg_address
(
sg
[
db
])
+
di
;
*
dst
=
*
src
;
}
...
...
@@ -605,7 +605,7 @@ int usb_stor_scsiSense10to6( Scsi_Cmnd* the10 )
break
;
}
*
(
char
*
)(
page_address
(
sg
[
db
].
page
)
+
sg
[
db
].
offset
)
=
0
;
*
(
char
*
)(
sg_address
(
sg
[
db
])
)
=
0
;
/* get next destination */
if
(
sg
[
db
].
length
-
1
==
di
)
...
...
@@ -756,8 +756,8 @@ int usb_stor_scsiSense6to10( Scsi_Cmnd* the6 )
/* copy one byte */
{
char
*
src
=
page_address
(
sg
[
sb
].
page
)
+
sg
[
sb
].
offset
+
si
;
char
*
dst
=
page_address
(
sg
[
db
].
page
)
+
sg
[
db
].
offset
+
di
;
char
*
src
=
sg_address
(
sg
[
sb
])
+
si
;
char
*
dst
=
sg_address
(
sg
[
db
])
+
di
;
*
dst
=
*
src
;
}
...
...
@@ -798,7 +798,7 @@ int usb_stor_scsiSense6to10( Scsi_Cmnd* the6 )
}
{
char
*
dst
=
page_address
(
sg
[
db
].
page
)
+
sg
[
db
].
offset
+
di
;
char
*
dst
=
sg_address
(
sg
[
db
])
+
di
;
*
dst
=
tempBuffer
[
element
-
USB_STOR_SCSI_SENSE_HDRSZ
];
}
...
...
@@ -852,17 +852,14 @@ void usb_stor_scsiSenseParseBuffer( Scsi_Cmnd* srb, Usb_Stor_Scsi_Sense_Hdr_u* t
if
(
element
<
USB_STOR_SCSI_SENSE_HDRSZ
)
{
/* fill in the pointers for both header types */
the6
->
array
[
element
]
=
page_address
(
sg
[
i
].
page
)
+
sg
[
i
].
offset
+
j
;
the10
->
array
[
element
]
=
page_address
(
sg
[
i
].
page
)
+
sg
[
i
].
offset
+
j
;
the6
->
array
[
element
]
=
sg_address
(
sg
[
i
])
+
j
;
the10
->
array
[
element
]
=
sg_address
(
sg
[
i
])
+
j
;
}
else
if
(
element
<
USB_STOR_SCSI_SENSE_10_HDRSZ
)
{
/* only the longer headers still cares now */
the10
->
array
[
element
]
=
page_address
(
sg
[
i
].
page
)
+
sg
[
i
].
offset
+
j
;
the10
->
array
[
element
]
=
sg_address
(
sg
[
i
])
+
j
;
}
/* increase element counter */
...
...
drivers/usb/storage/sddr09.c
View file @
dfd47943
...
...
@@ -1091,25 +1091,23 @@ sddr09_read_map(struct us_data *us) {
return
0
;
for
(
i
=
0
;
i
<
alloc_blocks
;
i
++
)
{
if
(
i
<
alloc_blocks
-
1
)
{
char
*
vaddr
=
kmalloc
(
1
<<
17
,
GFP_NOIO
);
sg
[
i
].
page
=
virt_to_page
(
vaddr
);
sg
[
i
].
offset
=
((
unsigned
long
)
vaddr
&
~
PAGE_MASK
);
sg
[
i
].
length
=
(
1
<<
17
);
}
else
{
char
*
vaddr
=
kmalloc
(
alloc_len
,
GFP_NOIO
);
sg
[
i
].
page
=
virt_to_page
(
vaddr
);
sg
[
i
].
offset
=
((
unsigned
long
)
vaddr
&
~
PAGE_MASK
);
sg
[
i
].
length
=
alloc_len
;
}
alloc_len
-=
sg
[
i
].
length
;
int
alloc_req
=
(
i
<
alloc_blocks
-
1
?
1
<<
17
:
alloc_len
);
char
*
vaddr
=
kmalloc
(
alloc_req
,
GFP_NOIO
);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,3)
sg
[
i
].
page
=
virt_to_page
(
vaddr
);
sg
[
i
].
offset
=
((
unsigned
long
)
vaddr
&
~
PAGE_MASK
);
#else
sg
[
i
].
address
=
vaddr
;
#endif
sg
[
i
].
length
=
alloc_req
;
alloc_len
-=
alloc_req
;
}
for
(
i
=
0
;
i
<
alloc_blocks
;
i
++
)
if
(
sg
[
i
].
page
==
NULL
)
{
for
(
i
=
0
;
i
<
alloc_blocks
;
i
++
)
if
(
sg
[
i
].
page
!=
NULL
)
kfree
(
page_address
(
sg
[
i
].
page
)
+
sg
[
i
].
offset
);
kfree
(
sg_address
(
sg
[
i
])
);
kfree
(
sg
);
return
0
;
}
...
...
@@ -1120,7 +1118,7 @@ sddr09_read_map(struct us_data *us) {
(
unsigned
char
*
)
sg
,
alloc_blocks
);
if
(
result
!=
USB_STOR_TRANSPORT_GOOD
)
{
for
(
i
=
0
;
i
<
alloc_blocks
;
i
++
)
kfree
(
page_address
(
sg
[
i
].
page
)
+
sg
[
i
].
offset
);
kfree
(
sg_address
(
sg
[
i
])
);
kfree
(
sg
);
return
-
1
;
}
...
...
@@ -1136,7 +1134,7 @@ sddr09_read_map(struct us_data *us) {
info
->
lba_to_pba
=
NULL
;
info
->
pba_to_lba
=
NULL
;
for
(
i
=
0
;
i
<
alloc_blocks
;
i
++
)
kfree
(
page_address
(
sg
[
i
].
page
)
+
sg
[
i
].
offset
);
kfree
(
sg_address
(
sg
[
i
])
);
kfree
(
sg
);
return
0
;
}
...
...
@@ -1144,7 +1142,7 @@ sddr09_read_map(struct us_data *us) {
for
(
i
=
0
;
i
<
numblocks
;
i
++
)
info
->
lba_to_pba
[
i
]
=
info
->
pba_to_lba
[
i
]
=
UNDEF
;
ptr
=
page_address
(
sg
[
0
].
page
)
+
sg
[
0
].
offset
;
ptr
=
sg_address
(
sg
[
0
])
;
/*
* Define lba-pba translation table
...
...
@@ -1153,8 +1151,7 @@ sddr09_read_map(struct us_data *us) {
// scatterlist block i*64/128k = i*(2^6)*(2^-17) = i*(2^-11)
for
(
i
=
0
;
i
<
numblocks
;
i
++
)
{
ptr
=
page_address
(
sg
[
i
>>
11
].
page
)
+
sg
[
i
>>
11
].
offset
+
((
i
&
0x7ff
)
<<
6
);
ptr
=
sg_address
(
sg
[
i
>>
11
])
+
((
i
&
0x7ff
)
<<
6
);
if
(
i
==
0
||
i
==
1
)
{
info
->
pba_to_lba
[
i
]
=
UNUSABLE
;
...
...
@@ -1264,7 +1261,7 @@ sddr09_read_map(struct us_data *us) {
US_DEBUGP
(
"Found %d LBA's
\n
"
,
lbact
);
for
(
i
=
0
;
i
<
alloc_blocks
;
i
++
)
kfree
(
page_address
(
sg
[
i
].
page
)
+
sg
[
i
].
offset
);
kfree
(
sg_address
(
sg
[
i
])
);
kfree
(
sg
);
return
0
;
}
...
...
drivers/usb/storage/shuttle_usbat.c
View file @
dfd47943
...
...
@@ -348,10 +348,13 @@ int usbat_rw_block_test(struct us_data *us,
* the bulk output pipe only the first time.
*/
if
(
direction
==
SCSI_DATA_READ
&&
i
==
0
)
usb_stor_clear_halt
(
us
,
if
(
direction
==
SCSI_DATA_READ
&&
i
==
0
)
{
if
(
usb_stor_clear_halt
(
us
,
usb_sndbulkpipe
(
us
->
pusb_dev
,
us
->
ep_out
));
us
->
ep_out
))
<
0
)
return
USB_STOR_TRANSPORT_ERROR
;
}
/*
* Read status: is the device angry, or just busy?
*/
...
...
drivers/usb/storage/transport.c
View file @
dfd47943
...
...
@@ -349,8 +349,8 @@ unsigned int usb_stor_transfer_length(Scsi_Cmnd *srb)
* all the complex logic above, let's find them and eliminate them.
*/
if
(
len
!=
srb
->
request_bufflen
)
{
printk
(
"USB len=%d, request_bufflen=%d
\n
"
,
len
,
srb
->
request_bufflen
);
show_trace
(
NULL
);
printk
(
KERN_ERR
"USB len=%d, request_bufflen=%d
\n
"
,
len
,
srb
->
request_bufflen
);
printk
(
KERN_ERR
"Fix this -- future 2.5 kernels will not work if this is not fixed!
\n
"
);
}
return
len
;
...
...
@@ -370,16 +370,20 @@ unsigned int usb_stor_transfer_length(Scsi_Cmnd *srb)
* as those occurring during device-specific initialization, must be handled
* by a separate code path.)
*
* The abort function first sets the machine state, then acquires the lock
* on the current_urb before checking if it needs to be aborted.
* The abort function first sets the machine state, then atomically
* tests-and-clears the CAN_CANCEL bit in us->flags to see if the current_urb
* needs to be aborted.
*
* When a function submits the current_urb, it must first grab the
* current_urb_sem to prevent the abort function from trying to cancel the
* URB while the submit call is underway. After a function submits the
* current_urb, it -MUST- test the state to see if we got aborted just before
* the submission. If so, it's essential to abort the URB if it's still in
* progress. Either way, the function must then release the lock and wait
* for the URB to finish.
* The submit function first verifies that the submission completed without
* errors, and only then sets the CAN_CANCEL bit. This prevents the abort
* function from trying to cancel the URB while the submit call is underway.
* Next, the submit function must test the state to see if we got aborted
* before the submission or before setting the CAN_CANCEL bit. If so, it's
* essential to abort the URB if it hasn't been cancelled already (i.e.,
* if the CAN_CANCEL bit is still set). Either way, the function must then
* wait for the URB to finish. Note that because the USB_ASYNC_UNLINK flag
* is set, the URB can still be in progress even after a call to
* usb_unlink_urb() returns.
*
* (It's also permissible, but not necessary, to test the state -before-
* submitting the URB. Doing so would prevent an unnecessary submission if
...
...
@@ -389,7 +393,7 @@ unsigned int usb_stor_transfer_length(Scsi_Cmnd *srb)
*
* The idea is that (1) once the state is changed to ABORTING, either the
* aborting function or the submitting function is guaranteed to call
* usb_unlink_urb() for an active URB, and (2)
current_urb_sem
prevents
* usb_unlink_urb() for an active URB, and (2)
test_and_clear_bit()
prevents
* usb_unlink_urb() from being called more than once or from being called
* during usb_submit_urb().
*/
...
...
@@ -424,28 +428,30 @@ static int usb_stor_msg_common(struct us_data *us)
us
->
current_urb
->
error_count
=
0
;
us
->
current_urb
->
transfer_flags
=
USB_ASYNC_UNLINK
;
/* lock and submit the URB */
down
(
&
(
us
->
current_urb_sem
));
/* submit the URB */
status
=
usb_submit_urb
(
us
->
current_urb
,
GFP_NOIO
);
if
(
status
)
{
/* something went wrong */
up
(
&
(
us
->
current_urb_sem
));
return
status
;
}
/* since the URB has been submitted successfully, it's now okay
* to cancel it */
set_bit
(
US_FLIDX_CAN_CANCEL
,
&
us
->
flags
);
/* has the current command been aborted? */
if
(
atomic_read
(
&
us
->
sm_state
)
==
US_STATE_ABORTING
)
{
/* cancel the URB, if it hasn't been cancelled already */
if
(
us
->
current_urb
->
status
==
-
EINPROGRESS
)
{
if
(
test_and_clear_bit
(
US_FLIDX_CAN_CANCEL
,
&
us
->
flags
)
)
{
US_DEBUGP
(
"-- cancelling URB
\n
"
);
usb_unlink_urb
(
us
->
current_urb
);
}
}
up
(
&
(
us
->
current_urb_sem
));
/* wait for the completion of the URB */
wait_for_completion
(
&
urb_done
);
clear_bit
(
US_FLIDX_CAN_CANCEL
,
&
us
->
flags
);
/* return the URB status */
return
us
->
current_urb
->
status
;
...
...
@@ -565,7 +571,8 @@ int usb_stor_transfer_partial(struct us_data *us, char *buf, int length)
/* if we stall, we need to clear it before we go on */
if
(
result
==
-
EPIPE
)
{
US_DEBUGP
(
"clearing endpoint halt for pipe 0x%x
\n
"
,
pipe
);
usb_stor_clear_halt
(
us
,
pipe
);
if
(
usb_stor_clear_halt
(
us
,
pipe
)
<
0
)
return
US_BULK_TRANSFER_FAILED
;
}
/* did we abort this command? */
...
...
@@ -635,11 +642,11 @@ void usb_stor_transfer(Scsi_Cmnd *srb, struct us_data* us)
if
(
transfer_amount
-
total_transferred
>=
sg
[
i
].
length
)
{
result
=
usb_stor_transfer_partial
(
us
,
page_address
(
sg
[
i
].
page
)
+
sg
[
i
].
offset
,
sg
[
i
].
length
);
sg_address
(
sg
[
i
])
,
sg
[
i
].
length
);
total_transferred
+=
sg
[
i
].
length
;
}
else
result
=
usb_stor_transfer_partial
(
us
,
page_address
(
sg
[
i
].
page
)
+
sg
[
i
].
offset
,
sg_address
(
sg
[
i
])
,
transfer_amount
-
total_transferred
);
/* if we get an error, end the loop here */
...
...
@@ -867,15 +874,13 @@ void usb_stor_abort_transport(struct us_data *us)
/* If the state machine is blocked waiting for an URB or an IRQ,
* let's wake it up */
/* If we have an URB pending, cancel it.
Note that we guarantee with
*
the current_urb_sem
that if a URB has just been submitted, it
/* If we have an URB pending, cancel it.
The test_and_clear_bit()
*
call guarantees
that if a URB has just been submitted, it
* won't be cancelled more than once. */
down
(
&
(
us
->
current_urb_sem
));
if
(
us
->
current_urb
->
status
==
-
EINPROGRESS
)
{
if
(
test_and_clear_bit
(
US_FLIDX_CAN_CANCEL
,
&
us
->
flags
))
{
US_DEBUGP
(
"-- cancelling URB
\n
"
);
usb_unlink_urb
(
us
->
current_urb
);
}
up
(
&
(
us
->
current_urb_sem
));
/* If we are waiting for an IRQ, simulate it */
if
(
test_bit
(
US_FLIDX_IP_WANTED
,
&
us
->
flags
))
{
...
...
@@ -993,18 +998,9 @@ int usb_stor_CBI_transport(Scsi_Cmnd *srb, struct us_data *us)
return
US_BULK_TRANSFER_ABORTED
;
}
/*
STALL must be cleared when it is detected
*/
/*
a stall indicates a protocol error
*/
if
(
result
==
-
EPIPE
)
{
US_DEBUGP
(
"-- Stall on control pipe. Clearing
\n
"
);
result
=
usb_stor_clear_halt
(
us
,
usb_sndctrlpipe
(
us
->
pusb_dev
,
0
));
/* did we abort this command? */
if
(
atomic_read
(
&
us
->
sm_state
)
==
US_STATE_ABORTING
)
{
US_DEBUGP
(
"usb_stor_control_msg(): transfer aborted
\n
"
);
return
US_BULK_TRANSFER_ABORTED
;
}
US_DEBUGP
(
"-- Stall on control pipe
\n
"
);
return
USB_STOR_TRANSPORT_FAILED
;
}
...
...
@@ -1110,17 +1106,9 @@ int usb_stor_CB_transport(Scsi_Cmnd *srb, struct us_data *us)
return
US_BULK_TRANSFER_ABORTED
;
}
/* a stall i
s a fatal condition from the device
*/
/* a stall i
ndicates a protocol error
*/
if
(
result
==
-
EPIPE
)
{
US_DEBUGP
(
"-- Stall on control pipe. Clearing
\n
"
);
result
=
usb_stor_clear_halt
(
us
,
usb_sndctrlpipe
(
us
->
pusb_dev
,
0
));
/* did we abort this command? */
if
(
atomic_read
(
&
us
->
sm_state
)
==
US_STATE_ABORTING
)
{
US_DEBUGP
(
"usb_stor_CB_transport(): transfer aborted
\n
"
);
return
US_BULK_TRANSFER_ABORTED
;
}
US_DEBUGP
(
"-- Stall on control pipe
\n
"
);
return
USB_STOR_TRANSPORT_FAILED
;
}
...
...
@@ -1178,15 +1166,6 @@ int usb_stor_Bulk_max_lun(struct us_data *us)
if
(
result
==
1
)
return
data
;
/* if we get a STALL, clear the stall */
if
(
result
==
-
EPIPE
)
{
US_DEBUGP
(
"clearing endpoint halt for pipe 0x%x
\n
"
,
pipe
);
/* Use usb_clear_halt() because this is not a
* scsi queued-command */
usb_clear_halt
(
us
->
pusb_dev
,
pipe
);
}
/* return the default -- no LUNs */
return
0
;
}
...
...
@@ -1241,6 +1220,8 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
US_DEBUGP
(
"usb_stor_Bulk_transport(): transfer aborted
\n
"
);
return
US_BULK_TRANSFER_ABORTED
;
}
if
(
result
<
0
)
return
USB_STOR_TRANSPORT_ERROR
;
result
=
-
EPIPE
;
}
else
if
(
result
)
{
/* unknown error -- we've got a problem */
...
...
@@ -1289,6 +1270,8 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
US_DEBUGP
(
"usb_stor_Bulk_transport(): transfer aborted
\n
"
);
return
US_BULK_TRANSFER_ABORTED
;
}
if
(
result
<
0
)
return
USB_STOR_TRANSPORT_ERROR
;
/* get the status again */
US_DEBUGP
(
"Attempting to get CSW (2nd try)...
\n
"
);
...
...
drivers/usb/storage/usb.c
View file @
dfd47943
...
...
@@ -283,13 +283,13 @@ void fill_inquiry_response(struct us_data *us, unsigned char *data,
if
(
us
->
srb
->
use_sg
)
{
sg
=
(
struct
scatterlist
*
)
us
->
srb
->
request_buffer
;
for
(
i
=
0
;
i
<
us
->
srb
->
use_sg
;
i
++
)
memset
(
page_address
(
sg
[
i
].
page
)
+
sg
[
i
].
offset
,
0
,
sg
[
i
].
length
);
memset
(
sg_address
(
sg
[
i
])
,
0
,
sg
[
i
].
length
);
for
(
i
=
0
,
transferred
=
0
;
i
<
us
->
srb
->
use_sg
&&
transferred
<
len
;
i
++
)
{
amt
=
sg
[
i
].
length
>
len
-
transferred
?
len
-
transferred
:
sg
[
i
].
length
;
memcpy
(
page_address
(
sg
[
i
].
page
)
+
sg
[
i
].
offset
,
data
+
transferred
,
amt
);
memcpy
(
sg_address
(
sg
[
i
])
,
data
+
transferred
,
amt
);
transferred
-=
amt
;
}
}
else
{
...
...
@@ -724,8 +724,7 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum,
US_DEBUGP
(
"Result from usb_set_configuration is %d
\n
"
,
result
);
if
(
result
==
-
EPIPE
)
{
US_DEBUGP
(
"-- clearing stall on control interface
\n
"
);
usb_clear_halt
(
dev
,
usb_sndctrlpipe
(
dev
,
0
));
US_DEBUGP
(
"-- stall on control interface
\n
"
);
}
else
if
(
result
!=
0
)
{
/* it's not a stall, but another error -- time to bail */
US_DEBUGP
(
"-- Unknown error. Rejecting device
\n
"
);
...
...
@@ -825,7 +824,6 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum,
init_completion
(
&
(
ss
->
notify
));
init_MUTEX_LOCKED
(
&
(
ss
->
ip_waitq
));
init_MUTEX
(
&
(
ss
->
irq_urb_sem
));
init_MUTEX
(
&
(
ss
->
current_urb_sem
));
init_MUTEX_LOCKED
(
&
(
ss
->
dev_semaphore
));
/* copy over the subclass and protocol data */
...
...
drivers/usb/storage/usb.h
View file @
dfd47943
...
...
@@ -106,6 +106,7 @@ struct us_unusual_dev {
#define US_FL_DEV_ATTACHED 0x00010000
/* is the device attached? */
#define US_FLIDX_IP_WANTED 17
/* 0x00020000 is an IRQ expected? */
#define US_FLIDX_CAN_CANCEL 18
/* 0x00040000 okay to cancel current_urb? */
/* processing state machine states */
...
...
@@ -177,7 +178,6 @@ struct us_data {
unsigned
char
irqdata
[
2
];
/* data from USB IRQ */
/* control and bulk communications data */
struct
semaphore
current_urb_sem
;
/* protect current_urb */
struct
urb
*
current_urb
;
/* non-int USB requests */
struct
usb_ctrlrequest
*
dr
;
/* control requests */
...
...
@@ -206,7 +206,6 @@ extern void fill_inquiry_response(struct us_data *us,
* single queue element srb for write access */
#define scsi_unlock(host) spin_unlock_irq(host->host_lock)
#define scsi_lock(host) spin_lock_irq(host->host_lock)
#define sg_address(psg) (page_address((psg)->page) + (psg)->offset)
#define sg_address(psg) (page_address((psg).page) + (psg).offset)
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment