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
8dcce408
Commit
8dcce408
authored
Jun 13, 2009
by
Bartlomiej Zolnierkiewicz
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'bp-remove-pc-buf' into for-next
Conflicts: drivers/ide/ide-tape.c
parents
f3ad1165
103f7033
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
230 additions
and
261 deletions
+230
-261
drivers/ide/ide-atapi.c
drivers/ide/ide-atapi.c
+87
-51
drivers/ide/ide-cd.c
drivers/ide/ide-cd.c
+11
-57
drivers/ide/ide-floppy.c
drivers/ide/ide-floppy.c
+22
-28
drivers/ide/ide-floppy_ioctl.c
drivers/ide/ide-floppy_ioctl.c
+23
-20
drivers/ide/ide-tape.c
drivers/ide/ide-tape.c
+83
-91
include/linux/ide.h
include/linux/ide.h
+4
-14
No files found.
drivers/ide/ide-atapi.c
View file @
8dcce408
...
@@ -10,6 +10,9 @@
...
@@ -10,6 +10,9 @@
#include <scsi/scsi.h>
#include <scsi/scsi.h>
#define DRV_NAME "ide-atapi"
#define PFX DRV_NAME ": "
#ifdef DEBUG
#ifdef DEBUG
#define debug_log(fmt, args...) \
#define debug_log(fmt, args...) \
printk(KERN_INFO "ide: " fmt, ## args)
printk(KERN_INFO "ide: " fmt, ## args)
...
@@ -74,8 +77,6 @@ EXPORT_SYMBOL_GPL(ide_check_atapi_device);
...
@@ -74,8 +77,6 @@ EXPORT_SYMBOL_GPL(ide_check_atapi_device);
void
ide_init_pc
(
struct
ide_atapi_pc
*
pc
)
void
ide_init_pc
(
struct
ide_atapi_pc
*
pc
)
{
{
memset
(
pc
,
0
,
sizeof
(
*
pc
));
memset
(
pc
,
0
,
sizeof
(
*
pc
));
pc
->
buf
=
pc
->
pc_buf
;
pc
->
buf_size
=
IDE_PC_BUFFER_SIZE
;
}
}
EXPORT_SYMBOL_GPL
(
ide_init_pc
);
EXPORT_SYMBOL_GPL
(
ide_init_pc
);
...
@@ -84,7 +85,7 @@ EXPORT_SYMBOL_GPL(ide_init_pc);
...
@@ -84,7 +85,7 @@ EXPORT_SYMBOL_GPL(ide_init_pc);
* and wait for it to be serviced.
* and wait for it to be serviced.
*/
*/
int
ide_queue_pc_tail
(
ide_drive_t
*
drive
,
struct
gendisk
*
disk
,
int
ide_queue_pc_tail
(
ide_drive_t
*
drive
,
struct
gendisk
*
disk
,
struct
ide_atapi_pc
*
pc
)
struct
ide_atapi_pc
*
pc
,
void
*
buf
,
unsigned
int
bufflen
)
{
{
struct
request
*
rq
;
struct
request
*
rq
;
int
error
;
int
error
;
...
@@ -93,8 +94,8 @@ int ide_queue_pc_tail(ide_drive_t *drive, struct gendisk *disk,
...
@@ -93,8 +94,8 @@ int ide_queue_pc_tail(ide_drive_t *drive, struct gendisk *disk,
rq
->
cmd_type
=
REQ_TYPE_SPECIAL
;
rq
->
cmd_type
=
REQ_TYPE_SPECIAL
;
rq
->
special
=
(
char
*
)
pc
;
rq
->
special
=
(
char
*
)
pc
;
if
(
pc
->
req_xfer
)
{
if
(
buf
&&
bufflen
)
{
error
=
blk_rq_map_kern
(
drive
->
queue
,
rq
,
pc
->
buf
,
pc
->
req_xfer
,
error
=
blk_rq_map_kern
(
drive
->
queue
,
rq
,
buf
,
bufflen
,
GFP_NOIO
);
GFP_NOIO
);
if
(
error
)
if
(
error
)
goto
put_req
;
goto
put_req
;
...
@@ -117,7 +118,7 @@ int ide_do_test_unit_ready(ide_drive_t *drive, struct gendisk *disk)
...
@@ -117,7 +118,7 @@ int ide_do_test_unit_ready(ide_drive_t *drive, struct gendisk *disk)
ide_init_pc
(
&
pc
);
ide_init_pc
(
&
pc
);
pc
.
c
[
0
]
=
TEST_UNIT_READY
;
pc
.
c
[
0
]
=
TEST_UNIT_READY
;
return
ide_queue_pc_tail
(
drive
,
disk
,
&
pc
);
return
ide_queue_pc_tail
(
drive
,
disk
,
&
pc
,
NULL
,
0
);
}
}
EXPORT_SYMBOL_GPL
(
ide_do_test_unit_ready
);
EXPORT_SYMBOL_GPL
(
ide_do_test_unit_ready
);
...
@@ -132,7 +133,7 @@ int ide_do_start_stop(ide_drive_t *drive, struct gendisk *disk, int start)
...
@@ -132,7 +133,7 @@ int ide_do_start_stop(ide_drive_t *drive, struct gendisk *disk, int start)
if
(
drive
->
media
==
ide_tape
)
if
(
drive
->
media
==
ide_tape
)
pc
.
flags
|=
PC_FLAG_WAIT_FOR_DSC
;
pc
.
flags
|=
PC_FLAG_WAIT_FOR_DSC
;
return
ide_queue_pc_tail
(
drive
,
disk
,
&
pc
);
return
ide_queue_pc_tail
(
drive
,
disk
,
&
pc
,
NULL
,
0
);
}
}
EXPORT_SYMBOL_GPL
(
ide_do_start_stop
);
EXPORT_SYMBOL_GPL
(
ide_do_start_stop
);
...
@@ -147,7 +148,7 @@ int ide_set_media_lock(ide_drive_t *drive, struct gendisk *disk, int on)
...
@@ -147,7 +148,7 @@ int ide_set_media_lock(ide_drive_t *drive, struct gendisk *disk, int on)
pc
.
c
[
0
]
=
ALLOW_MEDIUM_REMOVAL
;
pc
.
c
[
0
]
=
ALLOW_MEDIUM_REMOVAL
;
pc
.
c
[
4
]
=
on
;
pc
.
c
[
4
]
=
on
;
return
ide_queue_pc_tail
(
drive
,
disk
,
&
pc
);
return
ide_queue_pc_tail
(
drive
,
disk
,
&
pc
,
NULL
,
0
);
}
}
EXPORT_SYMBOL_GPL
(
ide_set_media_lock
);
EXPORT_SYMBOL_GPL
(
ide_set_media_lock
);
...
@@ -172,8 +173,6 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq)
...
@@ -172,8 +173,6 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq)
unsigned
int
cmd_len
,
sense_len
;
unsigned
int
cmd_len
,
sense_len
;
int
err
;
int
err
;
debug_log
(
"%s: enter
\n
"
,
__func__
);
switch
(
drive
->
media
)
{
switch
(
drive
->
media
)
{
case
ide_floppy
:
case
ide_floppy
:
cmd_len
=
255
;
cmd_len
=
255
;
...
@@ -201,8 +200,8 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq)
...
@@ -201,8 +200,8 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq)
GFP_NOIO
);
GFP_NOIO
);
if
(
unlikely
(
err
))
{
if
(
unlikely
(
err
))
{
if
(
printk_ratelimit
())
if
(
printk_ratelimit
())
printk
(
KERN_WARNING
"%s: failed to map sense buffer
\n
"
,
printk
(
KERN_WARNING
PFX
"%s: failed to map sense "
drive
->
name
);
"buffer
\n
"
,
drive
->
name
);
return
;
return
;
}
}
...
@@ -223,7 +222,7 @@ int ide_queue_sense_rq(ide_drive_t *drive, void *special)
...
@@ -223,7 +222,7 @@ int ide_queue_sense_rq(ide_drive_t *drive, void *special)
{
{
/* deferred failure from ide_prep_sense() */
/* deferred failure from ide_prep_sense() */
if
(
!
drive
->
sense_rq_armed
)
{
if
(
!
drive
->
sense_rq_armed
)
{
printk
(
KERN_WARNING
"%s: failed queue
sense request
\n
"
,
printk
(
KERN_WARNING
PFX
"%s: error queuing a
sense request
\n
"
,
drive
->
name
);
drive
->
name
);
return
-
ENOMEM
;
return
-
ENOMEM
;
}
}
...
@@ -255,8 +254,6 @@ void ide_retry_pc(ide_drive_t *drive)
...
@@ -255,8 +254,6 @@ void ide_retry_pc(ide_drive_t *drive)
/* init pc from sense_rq */
/* init pc from sense_rq */
ide_init_pc
(
pc
);
ide_init_pc
(
pc
);
memcpy
(
pc
->
c
,
sense_rq
->
cmd
,
12
);
memcpy
(
pc
->
c
,
sense_rq
->
cmd
,
12
);
pc
->
buf
=
bio_data
(
sense_rq
->
bio
);
/* pointer to mapped address */
pc
->
req_xfer
=
blk_rq_bytes
(
sense_rq
);
if
(
drive
->
media
==
ide_tape
)
if
(
drive
->
media
==
ide_tape
)
drive
->
atapi_flags
|=
IDE_AFLAG_IGNORE_DSC
;
drive
->
atapi_flags
|=
IDE_AFLAG_IGNORE_DSC
;
...
@@ -298,7 +295,7 @@ int ide_cd_expiry(ide_drive_t *drive)
...
@@ -298,7 +295,7 @@ int ide_cd_expiry(ide_drive_t *drive)
break
;
break
;
default:
default:
if
(
!
(
rq
->
cmd_flags
&
REQ_QUIET
))
if
(
!
(
rq
->
cmd_flags
&
REQ_QUIET
))
printk
(
KERN_INFO
"cmd 0x%x timed out
\n
"
,
printk
(
KERN_INFO
PFX
"cmd 0x%x timed out
\n
"
,
rq
->
cmd
[
0
]);
rq
->
cmd
[
0
]);
wait
=
0
;
wait
=
0
;
break
;
break
;
...
@@ -331,6 +328,55 @@ void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason)
...
@@ -331,6 +328,55 @@ void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason)
}
}
EXPORT_SYMBOL_GPL
(
ide_read_bcount_and_ireason
);
EXPORT_SYMBOL_GPL
(
ide_read_bcount_and_ireason
);
/*
* Check the contents of the interrupt reason register and attempt to recover if
* there are problems.
*
* Returns:
* - 0 if everything's ok
* - 1 if the request has to be terminated.
*/
int
ide_check_ireason
(
ide_drive_t
*
drive
,
struct
request
*
rq
,
int
len
,
int
ireason
,
int
rw
)
{
ide_hwif_t
*
hwif
=
drive
->
hwif
;
debug_log
(
"ireason: 0x%x, rw: 0x%x
\n
"
,
ireason
,
rw
);
if
(
ireason
==
(
!
rw
<<
1
))
return
0
;
else
if
(
ireason
==
(
rw
<<
1
))
{
printk
(
KERN_ERR
PFX
"%s: %s: wrong transfer direction!
\n
"
,
drive
->
name
,
__func__
);
if
(
dev_is_idecd
(
drive
))
ide_pad_transfer
(
drive
,
rw
,
len
);
}
else
if
(
!
rw
&&
ireason
==
ATAPI_COD
)
{
if
(
dev_is_idecd
(
drive
))
{
/*
* Some drives (ASUS) seem to tell us that status info
* is available. Just get it and ignore.
*/
(
void
)
hwif
->
tp_ops
->
read_status
(
hwif
);
return
0
;
}
}
else
{
if
(
ireason
&
ATAPI_COD
)
printk
(
KERN_ERR
PFX
"%s: CoD != 0 in %s
\n
"
,
drive
->
name
,
__func__
);
/* drive wants a command packet, or invalid ireason... */
printk
(
KERN_ERR
PFX
"%s: %s: bad interrupt reason 0x%02x
\n
"
,
drive
->
name
,
__func__
,
ireason
);
}
if
(
dev_is_idecd
(
drive
)
&&
rq
->
cmd_type
==
REQ_TYPE_ATA_PC
)
rq
->
cmd_flags
|=
REQ_FAILED
;
return
1
;
}
EXPORT_SYMBOL_GPL
(
ide_check_ireason
);
/*
/*
* This is the usual interrupt handler which will be called during a packet
* This is the usual interrupt handler which will be called during a packet
* command. We will transfer some of the data (as requested by the drive)
* command. We will transfer some of the data (as requested by the drive)
...
@@ -365,12 +411,12 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
...
@@ -365,12 +411,12 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
if
(
rc
||
(
drive
->
media
==
ide_tape
&&
(
stat
&
ATA_ERR
)))
{
if
(
rc
||
(
drive
->
media
==
ide_tape
&&
(
stat
&
ATA_ERR
)))
{
if
(
drive
->
media
==
ide_floppy
)
if
(
drive
->
media
==
ide_floppy
)
printk
(
KERN_ERR
"%s: DMA %s error
\n
"
,
printk
(
KERN_ERR
PFX
"%s: DMA %s error
\n
"
,
drive
->
name
,
rq_data_dir
(
pc
->
rq
)
drive
->
name
,
rq_data_dir
(
pc
->
rq
)
?
"write"
:
"read"
);
?
"write"
:
"read"
);
pc
->
flags
|=
PC_FLAG_DMA_ERROR
;
pc
->
flags
|=
PC_FLAG_DMA_ERROR
;
}
else
}
else
pc
->
xferred
=
pc
->
req_xfer
;
rq
->
resid_len
=
0
;
debug_log
(
"%s: DMA finished
\n
"
,
drive
->
name
);
debug_log
(
"%s: DMA finished
\n
"
,
drive
->
name
);
}
}
...
@@ -379,7 +425,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
...
@@ -379,7 +425,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
int
uptodate
,
error
;
int
uptodate
,
error
;
debug_log
(
"Packet command completed, %d bytes transferred
\n
"
,
debug_log
(
"Packet command completed, %d bytes transferred
\n
"
,
pc
->
xferred
);
blk_rq_bytes
(
rq
)
);
pc
->
flags
&=
~
PC_FLAG_DMA_IN_PROGRESS
;
pc
->
flags
&=
~
PC_FLAG_DMA_IN_PROGRESS
;
...
@@ -397,8 +443,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
...
@@ -397,8 +443,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
pc
->
rq
->
errors
++
;
pc
->
rq
->
errors
++
;
if
(
rq
->
cmd
[
0
]
==
REQUEST_SENSE
)
{
if
(
rq
->
cmd
[
0
]
==
REQUEST_SENSE
)
{
printk
(
KERN_ERR
"%s: I/O error in request sense
"
printk
(
KERN_ERR
PFX
"%s: I/O error in request
"
" command
\n
"
,
drive
->
name
);
"
sense
command
\n
"
,
drive
->
name
);
return
ide_do_reset
(
drive
);
return
ide_do_reset
(
drive
);
}
}
...
@@ -446,8 +492,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
...
@@ -446,8 +492,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
if
(
pc
->
flags
&
PC_FLAG_DMA_IN_PROGRESS
)
{
if
(
pc
->
flags
&
PC_FLAG_DMA_IN_PROGRESS
)
{
pc
->
flags
&=
~
PC_FLAG_DMA_IN_PROGRESS
;
pc
->
flags
&=
~
PC_FLAG_DMA_IN_PROGRESS
;
printk
(
KERN_ERR
"%s: The device wants to issue more interrupts
"
printk
(
KERN_ERR
PFX
"%s: The device wants to issue more
"
"in DMA mode
\n
"
,
drive
->
name
);
"in
terrupts in
DMA mode
\n
"
,
drive
->
name
);
ide_dma_off
(
drive
);
ide_dma_off
(
drive
);
return
ide_do_reset
(
drive
);
return
ide_do_reset
(
drive
);
}
}
...
@@ -455,33 +501,22 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
...
@@ -455,33 +501,22 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
/* Get the number of bytes to transfer on this interrupt. */
/* Get the number of bytes to transfer on this interrupt. */
ide_read_bcount_and_ireason
(
drive
,
&
bcount
,
&
ireason
);
ide_read_bcount_and_ireason
(
drive
,
&
bcount
,
&
ireason
);
if
(
ireason
&
ATAPI_COD
)
{
if
(
ide_check_ireason
(
drive
,
rq
,
bcount
,
ireason
,
write
))
printk
(
KERN_ERR
"%s: CoD != 0 in %s
\n
"
,
drive
->
name
,
__func__
);
return
ide_do_reset
(
drive
);
return
ide_do_reset
(
drive
);
}
if
(((
ireason
&
ATAPI_IO
)
==
ATAPI_IO
)
==
write
)
{
/* Hopefully, we will never get here */
printk
(
KERN_ERR
"%s: We wanted to %s, but the device wants us "
"to %s!
\n
"
,
drive
->
name
,
(
ireason
&
ATAPI_IO
)
?
"Write"
:
"Read"
,
(
ireason
&
ATAPI_IO
)
?
"Read"
:
"Write"
);
return
ide_do_reset
(
drive
);
}
done
=
min_t
(
unsigned
int
,
bcount
,
cmd
->
nleft
);
done
=
min_t
(
unsigned
int
,
bcount
,
cmd
->
nleft
);
ide_pio_bytes
(
drive
,
cmd
,
write
,
done
);
ide_pio_bytes
(
drive
,
cmd
,
write
,
done
);
/* Update transferred byte count */
/* Update transferred byte count */
pc
->
xferred
+
=
done
;
rq
->
resid_len
-
=
done
;
bcount
-=
done
;
bcount
-=
done
;
if
(
bcount
)
if
(
bcount
)
ide_pad_transfer
(
drive
,
write
,
bcount
);
ide_pad_transfer
(
drive
,
write
,
bcount
);
debug_log
(
"[cmd %x] transferred %d bytes, padded %d bytes
\n
"
,
debug_log
(
"[cmd %x] transferred %d bytes, padded %d bytes
, resid: %u
\n
"
,
rq
->
cmd
[
0
],
done
,
bcount
);
rq
->
cmd
[
0
],
done
,
bcount
,
rq
->
resid_len
);
/* And set the interrupt handler again */
/* And set the interrupt handler again */
ide_set_handler
(
drive
,
ide_pc_intr
,
timeout
);
ide_set_handler
(
drive
,
ide_pc_intr
,
timeout
);
...
@@ -515,13 +550,13 @@ static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason)
...
@@ -515,13 +550,13 @@ static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason)
while
(
retries
--
&&
((
ireason
&
ATAPI_COD
)
==
0
||
while
(
retries
--
&&
((
ireason
&
ATAPI_COD
)
==
0
||
(
ireason
&
ATAPI_IO
)))
{
(
ireason
&
ATAPI_IO
)))
{
printk
(
KERN_ERR
"%s: (IO,CoD != (0,1) while issuing "
printk
(
KERN_ERR
PFX
"%s: (IO,CoD != (0,1) while issuing "
"a packet command, retrying
\n
"
,
drive
->
name
);
"a packet command, retrying
\n
"
,
drive
->
name
);
udelay
(
100
);
udelay
(
100
);
ireason
=
ide_read_ireason
(
drive
);
ireason
=
ide_read_ireason
(
drive
);
if
(
retries
==
0
)
{
if
(
retries
==
0
)
{
printk
(
KERN_ERR
"%s: (IO,CoD != (0,1) while issuing
"
printk
(
KERN_ERR
PFX
"%s: (IO,CoD != (0,1) while issuing
"
"a packet command, ignoring
\n
"
,
"
a packet command, ignoring
\n
"
,
drive
->
name
);
drive
->
name
);
ireason
|=
ATAPI_COD
;
ireason
|=
ATAPI_COD
;
ireason
&=
~
ATAPI_IO
;
ireason
&=
~
ATAPI_IO
;
...
@@ -552,7 +587,7 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
...
@@ -552,7 +587,7 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
u8
ireason
;
u8
ireason
;
if
(
ide_wait_stat
(
&
startstop
,
drive
,
ATA_DRQ
,
ATA_BUSY
,
WAIT_READY
))
{
if
(
ide_wait_stat
(
&
startstop
,
drive
,
ATA_DRQ
,
ATA_BUSY
,
WAIT_READY
))
{
printk
(
KERN_ERR
"%s: Strange, packet command initiated yet "
printk
(
KERN_ERR
PFX
"%s: Strange, packet command initiated yet "
"DRQ isn't asserted
\n
"
,
drive
->
name
);
"DRQ isn't asserted
\n
"
,
drive
->
name
);
return
startstop
;
return
startstop
;
}
}
...
@@ -594,8 +629,8 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
...
@@ -594,8 +629,8 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
ireason
=
ide_wait_ireason
(
drive
,
ireason
);
ireason
=
ide_wait_ireason
(
drive
,
ireason
);
if
((
ireason
&
ATAPI_COD
)
==
0
||
(
ireason
&
ATAPI_IO
))
{
if
((
ireason
&
ATAPI_COD
)
==
0
||
(
ireason
&
ATAPI_IO
))
{
printk
(
KERN_ERR
"%s: (IO,CoD) != (0,1) while issuing
"
printk
(
KERN_ERR
PFX
"%s: (IO,CoD) != (0,1) while
"
"
a packet command
\n
"
,
drive
->
name
);
"issuing
a packet command
\n
"
,
drive
->
name
);
return
ide_do_reset
(
drive
);
return
ide_do_reset
(
drive
);
}
}
...
@@ -633,7 +668,7 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd)
...
@@ -633,7 +668,7 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd)
ide_hwif_t
*
hwif
=
drive
->
hwif
;
ide_hwif_t
*
hwif
=
drive
->
hwif
;
ide_expiry_t
*
expiry
=
NULL
;
ide_expiry_t
*
expiry
=
NULL
;
struct
request
*
rq
=
hwif
->
rq
;
struct
request
*
rq
=
hwif
->
rq
;
unsigned
int
timeout
;
unsigned
int
timeout
,
bytes
;
u16
bcount
;
u16
bcount
;
u8
valid_tf
;
u8
valid_tf
;
u8
drq_int
=
!!
(
drive
->
atapi_flags
&
IDE_AFLAG_DRQ_INTERRUPT
);
u8
drq_int
=
!!
(
drive
->
atapi_flags
&
IDE_AFLAG_DRQ_INTERRUPT
);
...
@@ -649,13 +684,14 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd)
...
@@ -649,13 +684,14 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd)
}
else
{
}
else
{
pc
=
drive
->
pc
;
pc
=
drive
->
pc
;
/* We haven't transferred any data yet */
pc
->
xferred
=
0
;
valid_tf
=
IDE_VALID_DEVICE
;
valid_tf
=
IDE_VALID_DEVICE
;
bcount
=
((
drive
->
media
==
ide_tape
)
?
bytes
=
blk_rq_bytes
(
rq
);
pc
->
req_xfer
:
bcount
=
((
drive
->
media
==
ide_tape
)
?
bytes
min
(
pc
->
req_xfer
,
63
*
1024
));
:
min_t
(
unsigned
int
,
bytes
,
63
*
1024
));
/* We haven't transferred any data yet */
rq
->
resid_len
=
bcount
;
if
(
pc
->
flags
&
PC_FLAG_DMA_ERROR
)
{
if
(
pc
->
flags
&
PC_FLAG_DMA_ERROR
)
{
pc
->
flags
&=
~
PC_FLAG_DMA_ERROR
;
pc
->
flags
&=
~
PC_FLAG_DMA_ERROR
;
...
...
drivers/ide/ide-cd.c
View file @
8dcce408
...
@@ -92,16 +92,16 @@ static void cdrom_saw_media_change(ide_drive_t *drive)
...
@@ -92,16 +92,16 @@ static void cdrom_saw_media_change(ide_drive_t *drive)
drive
->
atapi_flags
&=
~
IDE_AFLAG_TOC_VALID
;
drive
->
atapi_flags
&=
~
IDE_AFLAG_TOC_VALID
;
}
}
static
int
cdrom_log_sense
(
ide_drive_t
*
drive
,
struct
request
*
rq
,
static
int
cdrom_log_sense
(
ide_drive_t
*
drive
,
struct
request
*
rq
)
struct
request_sense
*
sense
)
{
{
struct
request_sense
*
sense
=
&
drive
->
sense_data
;
int
log
=
0
;
int
log
=
0
;
ide_debug_log
(
IDE_DBG_SENSE
,
"sense_key: 0x%x"
,
sense
->
sense_key
);
if
(
!
sense
||
!
rq
||
(
rq
->
cmd_flags
&
REQ_QUIET
))
if
(
!
sense
||
!
rq
||
(
rq
->
cmd_flags
&
REQ_QUIET
))
return
0
;
return
0
;
ide_debug_log
(
IDE_DBG_SENSE
,
"sense_key: 0x%x"
,
sense
->
sense_key
);
switch
(
sense
->
sense_key
)
{
switch
(
sense
->
sense_key
)
{
case
NO_SENSE
:
case
NO_SENSE
:
case
RECOVERED_ERROR
:
case
RECOVERED_ERROR
:
...
@@ -140,12 +140,12 @@ static int cdrom_log_sense(ide_drive_t *drive, struct request *rq,
...
@@ -140,12 +140,12 @@ static int cdrom_log_sense(ide_drive_t *drive, struct request *rq,
}
}
static
void
cdrom_analyze_sense_data
(
ide_drive_t
*
drive
,
static
void
cdrom_analyze_sense_data
(
ide_drive_t
*
drive
,
struct
request
*
failed_command
,
struct
request
*
failed_command
)
struct
request_sense
*
sense
)
{
{
struct
request_sense
*
sense
=
&
drive
->
sense_data
;
struct
cdrom_info
*
info
=
drive
->
driver_data
;
unsigned
long
sector
;
unsigned
long
sector
;
unsigned
long
bio_sectors
;
unsigned
long
bio_sectors
;
struct
cdrom_info
*
info
=
drive
->
driver_data
;
ide_debug_log
(
IDE_DBG_SENSE
,
"error_code: 0x%x, sense_key: 0x%x"
,
ide_debug_log
(
IDE_DBG_SENSE
,
"error_code: 0x%x, sense_key: 0x%x"
,
sense
->
error_code
,
sense
->
sense_key
);
sense
->
error_code
,
sense
->
sense_key
);
...
@@ -154,7 +154,7 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive,
...
@@ -154,7 +154,7 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive,
ide_debug_log
(
IDE_DBG_SENSE
,
"failed cmd: 0x%x"
,
ide_debug_log
(
IDE_DBG_SENSE
,
"failed cmd: 0x%x"
,
failed_command
->
cmd
[
0
]);
failed_command
->
cmd
[
0
]);
if
(
!
cdrom_log_sense
(
drive
,
failed_command
,
sense
))
if
(
!
cdrom_log_sense
(
drive
,
failed_command
))
return
;
return
;
/*
/*
...
@@ -225,15 +225,14 @@ static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq)
...
@@ -225,15 +225,14 @@ static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq)
* sense pointer set.
* sense pointer set.
*/
*/
memcpy
(
failed
->
sense
,
sense
,
18
);
memcpy
(
failed
->
sense
,
sense
,
18
);
sense
=
failed
->
sense
;
failed
->
sense_len
=
rq
->
sense_len
;
failed
->
sense_len
=
rq
->
sense_len
;
}
}
cdrom_analyze_sense_data
(
drive
,
failed
,
sense
);
cdrom_analyze_sense_data
(
drive
,
failed
);
if
(
ide_end_rq
(
drive
,
failed
,
-
EIO
,
blk_rq_bytes
(
failed
)))
if
(
ide_end_rq
(
drive
,
failed
,
-
EIO
,
blk_rq_bytes
(
failed
)))
BUG
();
BUG
();
}
else
}
else
cdrom_analyze_sense_data
(
drive
,
NULL
,
sense
);
cdrom_analyze_sense_data
(
drive
,
NULL
);
}
}
...
@@ -410,50 +409,6 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat)
...
@@ -410,50 +409,6 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat)
return
2
;
return
2
;
}
}
/*
* Check the contents of the interrupt reason register from the cdrom
* and attempt to recover if there are problems. Returns 0 if everything's
* ok; nonzero if the request has been terminated.
*/
static
int
ide_cd_check_ireason
(
ide_drive_t
*
drive
,
struct
request
*
rq
,
int
len
,
int
ireason
,
int
rw
)
{
ide_hwif_t
*
hwif
=
drive
->
hwif
;
ide_debug_log
(
IDE_DBG_FUNC
,
"ireason: 0x%x, rw: 0x%x"
,
ireason
,
rw
);
/*
* ireason == 0: the drive wants to receive data from us
* ireason == 2: the drive is expecting to transfer data to us
*/
if
(
ireason
==
(
!
rw
<<
1
))
return
0
;
else
if
(
ireason
==
(
rw
<<
1
))
{
/* whoops... */
printk
(
KERN_ERR
PFX
"%s: %s: wrong transfer direction!
\n
"
,
drive
->
name
,
__func__
);
ide_pad_transfer
(
drive
,
rw
,
len
);
}
else
if
(
rw
==
0
&&
ireason
==
1
)
{
/*
* Some drives (ASUS) seem to tell us that status info is
* available. Just get it and ignore.
*/
(
void
)
hwif
->
tp_ops
->
read_status
(
hwif
);
return
0
;
}
else
{
/* drive wants a command packet, or invalid ireason... */
printk
(
KERN_ERR
PFX
"%s: %s: bad interrupt reason 0x%02x
\n
"
,
drive
->
name
,
__func__
,
ireason
);
}
if
(
rq
->
cmd_type
==
REQ_TYPE_ATA_PC
)
rq
->
cmd_flags
|=
REQ_FAILED
;
return
-
1
;
}
static
void
ide_cd_request_sense_fixup
(
ide_drive_t
*
drive
,
struct
ide_cmd
*
cmd
)
static
void
ide_cd_request_sense_fixup
(
ide_drive_t
*
drive
,
struct
ide_cmd
*
cmd
)
{
{
struct
request
*
rq
=
cmd
->
rq
;
struct
request
*
rq
=
cmd
->
rq
;
...
@@ -645,8 +600,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
...
@@ -645,8 +600,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
goto
out_end
;
goto
out_end
;
}
}
/* check which way to transfer data */
rc
=
ide_check_ireason
(
drive
,
rq
,
len
,
ireason
,
write
);
rc
=
ide_cd_check_ireason
(
drive
,
rq
,
len
,
ireason
,
write
);
if
(
rc
)
if
(
rc
)
goto
out_end
;
goto
out_end
;
...
...
drivers/ide/ide-floppy.c
View file @
8dcce408
...
@@ -77,7 +77,8 @@ static int ide_floppy_callback(ide_drive_t *drive, int dsc)
...
@@ -77,7 +77,8 @@ static int ide_floppy_callback(ide_drive_t *drive, int dsc)
(
rq
&&
blk_pc_request
(
rq
)))
(
rq
&&
blk_pc_request
(
rq
)))
uptodate
=
1
;
/* FIXME */
uptodate
=
1
;
/* FIXME */
else
if
(
pc
->
c
[
0
]
==
GPCMD_REQUEST_SENSE
)
{
else
if
(
pc
->
c
[
0
]
==
GPCMD_REQUEST_SENSE
)
{
u8
*
buf
=
pc
->
buf
;
u8
*
buf
=
bio_data
(
rq
->
bio
);
if
(
!
pc
->
error
)
{
if
(
!
pc
->
error
)
{
floppy
->
sense_key
=
buf
[
2
]
&
0x0F
;
floppy
->
sense_key
=
buf
[
2
]
&
0x0F
;
...
@@ -209,8 +210,7 @@ static void idefloppy_create_rw_cmd(ide_drive_t *drive,
...
@@ -209,8 +210,7 @@ static void idefloppy_create_rw_cmd(ide_drive_t *drive,
pc
->
rq
=
rq
;
pc
->
rq
=
rq
;
if
(
rq
->
cmd_flags
&
REQ_RW
)
if
(
rq
->
cmd_flags
&
REQ_RW
)
pc
->
flags
|=
PC_FLAG_WRITING
;
pc
->
flags
|=
PC_FLAG_WRITING
;
pc
->
buf
=
NULL
;
pc
->
req_xfer
=
pc
->
buf_size
=
blocks
*
floppy
->
block_size
;
pc
->
flags
|=
PC_FLAG_DMA_OK
;
pc
->
flags
|=
PC_FLAG_DMA_OK
;
}
}
...
@@ -225,9 +225,6 @@ static void idefloppy_blockpc_cmd(struct ide_disk_obj *floppy,
...
@@ -225,9 +225,6 @@ static void idefloppy_blockpc_cmd(struct ide_disk_obj *floppy,
if
(
rq_data_dir
(
rq
)
==
WRITE
)
if
(
rq_data_dir
(
rq
)
==
WRITE
)
pc
->
flags
|=
PC_FLAG_WRITING
;
pc
->
flags
|=
PC_FLAG_WRITING
;
}
}
/* pio will be performed by ide_pio_bytes() which handles sg fine */
pc
->
buf
=
NULL
;
pc
->
req_xfer
=
pc
->
buf_size
=
blk_rq_bytes
(
rq
);
}
}
static
ide_startstop_t
ide_floppy_do_request
(
ide_drive_t
*
drive
,
static
ide_startstop_t
ide_floppy_do_request
(
ide_drive_t
*
drive
,
...
@@ -286,8 +283,8 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
...
@@ -286,8 +283,8 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
cmd
.
rq
=
rq
;
cmd
.
rq
=
rq
;
if
(
blk_fs_request
(
rq
)
||
pc
->
req_xfer
)
{
if
(
blk_fs_request
(
rq
)
||
blk_rq_bytes
(
rq
)
)
{
ide_init_sg_cmd
(
&
cmd
,
pc
->
req_xfer
);
ide_init_sg_cmd
(
&
cmd
,
blk_rq_bytes
(
rq
)
);
ide_map_sg
(
drive
,
&
cmd
);
ide_map_sg
(
drive
,
&
cmd
);
}
}
...
@@ -311,33 +308,33 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive,
...
@@ -311,33 +308,33 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive,
{
{
struct
ide_disk_obj
*
floppy
=
drive
->
driver_data
;
struct
ide_disk_obj
*
floppy
=
drive
->
driver_data
;
struct
gendisk
*
disk
=
floppy
->
disk
;
struct
gendisk
*
disk
=
floppy
->
disk
;
u8
*
page
;
u8
*
page
,
buf
[
40
]
;
int
capacity
,
lba_capacity
;
int
capacity
,
lba_capacity
;
u16
transfer_rate
,
sector_size
,
cyls
,
rpm
;
u16
transfer_rate
,
sector_size
,
cyls
,
rpm
;
u8
heads
,
sectors
;
u8
heads
,
sectors
;
ide_floppy_create_mode_sense_cmd
(
pc
,
IDEFLOPPY_FLEXIBLE_DISK_PAGE
);
ide_floppy_create_mode_sense_cmd
(
pc
,
IDEFLOPPY_FLEXIBLE_DISK_PAGE
);
if
(
ide_queue_pc_tail
(
drive
,
disk
,
pc
))
{
if
(
ide_queue_pc_tail
(
drive
,
disk
,
pc
,
buf
,
pc
->
req_xfer
))
{
printk
(
KERN_ERR
PFX
"Can't get flexible disk page params
\n
"
);
printk
(
KERN_ERR
PFX
"Can't get flexible disk page params
\n
"
);
return
1
;
return
1
;
}
}
if
(
pc
->
buf
[
3
]
&
0x80
)
if
(
buf
[
3
]
&
0x80
)
drive
->
dev_flags
|=
IDE_DFLAG_WP
;
drive
->
dev_flags
|=
IDE_DFLAG_WP
;
else
else
drive
->
dev_flags
&=
~
IDE_DFLAG_WP
;
drive
->
dev_flags
&=
~
IDE_DFLAG_WP
;
set_disk_ro
(
disk
,
!!
(
drive
->
dev_flags
&
IDE_DFLAG_WP
));
set_disk_ro
(
disk
,
!!
(
drive
->
dev_flags
&
IDE_DFLAG_WP
));
page
=
&
pc
->
buf
[
8
];
page
=
&
buf
[
8
];
transfer_rate
=
be16_to_cpup
((
__be16
*
)
&
pc
->
buf
[
8
+
2
]);
transfer_rate
=
be16_to_cpup
((
__be16
*
)
&
buf
[
8
+
2
]);
sector_size
=
be16_to_cpup
((
__be16
*
)
&
pc
->
buf
[
8
+
6
]);
sector_size
=
be16_to_cpup
((
__be16
*
)
&
buf
[
8
+
6
]);
cyls
=
be16_to_cpup
((
__be16
*
)
&
pc
->
buf
[
8
+
8
]);
cyls
=
be16_to_cpup
((
__be16
*
)
&
buf
[
8
+
8
]);
rpm
=
be16_to_cpup
((
__be16
*
)
&
pc
->
buf
[
8
+
28
]);
rpm
=
be16_to_cpup
((
__be16
*
)
&
buf
[
8
+
28
]);
heads
=
pc
->
buf
[
8
+
4
];
heads
=
buf
[
8
+
4
];
sectors
=
pc
->
buf
[
8
+
5
];
sectors
=
buf
[
8
+
5
];
capacity
=
cyls
*
heads
*
sectors
*
sector_size
;
capacity
=
cyls
*
heads
*
sectors
*
sector_size
;
...
@@ -387,22 +384,19 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
...
@@ -387,22 +384,19 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
drive
->
capacity64
=
0
;
drive
->
capacity64
=
0
;
ide_floppy_create_read_capacity_cmd
(
&
pc
);
ide_floppy_create_read_capacity_cmd
(
&
pc
);
pc
.
buf
=
&
pc_buf
[
0
];
if
(
ide_queue_pc_tail
(
drive
,
disk
,
&
pc
,
pc_buf
,
pc
.
req_xfer
))
{
pc
.
buf_size
=
sizeof
(
pc_buf
);
if
(
ide_queue_pc_tail
(
drive
,
disk
,
&
pc
))
{
printk
(
KERN_ERR
PFX
"Can't get floppy parameters
\n
"
);
printk
(
KERN_ERR
PFX
"Can't get floppy parameters
\n
"
);
return
1
;
return
1
;
}
}
header_len
=
pc
.
buf
[
3
];
header_len
=
pc
_
buf
[
3
];
cap_desc
=
&
pc
.
buf
[
4
];
cap_desc
=
&
pc
_
buf
[
4
];
desc_cnt
=
header_len
/
8
;
/* capacity descriptor of 8 bytes */
desc_cnt
=
header_len
/
8
;
/* capacity descriptor of 8 bytes */
for
(
i
=
0
;
i
<
desc_cnt
;
i
++
)
{
for
(
i
=
0
;
i
<
desc_cnt
;
i
++
)
{
unsigned
int
desc_start
=
4
+
i
*
8
;
unsigned
int
desc_start
=
4
+
i
*
8
;
blocks
=
be32_to_cpup
((
__be32
*
)
&
pc
.
buf
[
desc_start
]);
blocks
=
be32_to_cpup
((
__be32
*
)
&
pc
_
buf
[
desc_start
]);
length
=
be16_to_cpup
((
__be16
*
)
&
pc
.
buf
[
desc_start
+
6
]);
length
=
be16_to_cpup
((
__be16
*
)
&
pc
_
buf
[
desc_start
+
6
]);
ide_debug_log
(
IDE_DBG_PROBE
,
"Descriptor %d: %dkB, %d blocks, "
ide_debug_log
(
IDE_DBG_PROBE
,
"Descriptor %d: %dkB, %d blocks, "
"%d sector size"
,
"%d sector size"
,
...
@@ -415,7 +409,7 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
...
@@ -415,7 +409,7 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
* the code below is valid only for the 1st descriptor, ie i=0
* the code below is valid only for the 1st descriptor, ie i=0
*/
*/
switch
(
pc
.
buf
[
desc_start
+
4
]
&
0x03
)
{
switch
(
pc
_
buf
[
desc_start
+
4
]
&
0x03
)
{
/* Clik! drive returns this instead of CAPACITY_CURRENT */
/* Clik! drive returns this instead of CAPACITY_CURRENT */
case
CAPACITY_UNFORMATTED
:
case
CAPACITY_UNFORMATTED
:
if
(
!
(
drive
->
atapi_flags
&
IDE_AFLAG_CLIK_DRIVE
))
if
(
!
(
drive
->
atapi_flags
&
IDE_AFLAG_CLIK_DRIVE
))
...
@@ -464,7 +458,7 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
...
@@ -464,7 +458,7 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
break
;
break
;
}
}
ide_debug_log
(
IDE_DBG_PROBE
,
"Descriptor 0 Code: %d"
,
ide_debug_log
(
IDE_DBG_PROBE
,
"Descriptor 0 Code: %d"
,
pc
.
buf
[
desc_start
+
4
]
&
0x03
);
pc
_
buf
[
desc_start
+
4
]
&
0x03
);
}
}
/* Clik! disk does not support get_flexible_disk_page */
/* Clik! disk does not support get_flexible_disk_page */
...
...
drivers/ide/ide-floppy_ioctl.c
View file @
8dcce408
...
@@ -47,15 +47,13 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive,
...
@@ -47,15 +47,13 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive,
return
-
EINVAL
;
return
-
EINVAL
;
ide_floppy_create_read_capacity_cmd
(
pc
);
ide_floppy_create_read_capacity_cmd
(
pc
);
pc
->
buf
=
&
pc_buf
[
0
];
pc
->
buf_size
=
sizeof
(
pc_buf
);
if
(
ide_queue_pc_tail
(
drive
,
floppy
->
disk
,
pc
))
{
if
(
ide_queue_pc_tail
(
drive
,
floppy
->
disk
,
pc
,
pc_buf
,
pc
->
req_xfer
))
{
printk
(
KERN_ERR
"ide-floppy: Can't get floppy parameters
\n
"
);
printk
(
KERN_ERR
"ide-floppy: Can't get floppy parameters
\n
"
);
return
-
EIO
;
return
-
EIO
;
}
}
header_len
=
pc
->
buf
[
3
];
header_len
=
pc
_
buf
[
3
];
desc_cnt
=
header_len
/
8
;
/* capacity descriptor of 8 bytes */
desc_cnt
=
header_len
/
8
;
/* capacity descriptor of 8 bytes */
u_index
=
0
;
u_index
=
0
;
...
@@ -72,8 +70,8 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive,
...
@@ -72,8 +70,8 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive,
if
(
u_index
>=
u_array_size
)
if
(
u_index
>=
u_array_size
)
break
;
/* User-supplied buffer too small */
break
;
/* User-supplied buffer too small */
blocks
=
be32_to_cpup
((
__be32
*
)
&
pc
->
buf
[
desc_start
]);
blocks
=
be32_to_cpup
((
__be32
*
)
&
pc
_
buf
[
desc_start
]);
length
=
be16_to_cpup
((
__be16
*
)
&
pc
->
buf
[
desc_start
+
6
]);
length
=
be16_to_cpup
((
__be16
*
)
&
pc
_
buf
[
desc_start
+
6
]);
if
(
put_user
(
blocks
,
argp
))
if
(
put_user
(
blocks
,
argp
))
return
-
EFAULT
;
return
-
EFAULT
;
...
@@ -94,40 +92,42 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive,
...
@@ -94,40 +92,42 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive,
return
0
;
return
0
;
}
}
static
void
ide_floppy_create_format_unit_cmd
(
struct
ide_atapi_pc
*
pc
,
int
b
,
static
void
ide_floppy_create_format_unit_cmd
(
struct
ide_atapi_pc
*
pc
,
int
l
,
int
flags
)
u8
*
buf
,
int
b
,
int
l
,
int
flags
)
{
{
ide_init_pc
(
pc
);
ide_init_pc
(
pc
);
pc
->
c
[
0
]
=
GPCMD_FORMAT_UNIT
;
pc
->
c
[
0
]
=
GPCMD_FORMAT_UNIT
;
pc
->
c
[
1
]
=
0x17
;
pc
->
c
[
1
]
=
0x17
;
memset
(
pc
->
buf
,
0
,
12
);
memset
(
buf
,
0
,
12
);
pc
->
buf
[
1
]
=
0xA2
;
buf
[
1
]
=
0xA2
;
/* Default format list header, u8 1: FOV/DCRT/IMM bits set */
/* Default format list header, u8 1: FOV/DCRT/IMM bits set */
if
(
flags
&
1
)
/* Verify bit on... */
if
(
flags
&
1
)
/* Verify bit on... */
pc
->
buf
[
1
]
^=
0x20
;
/* ... turn off DCRT bit */
buf
[
1
]
^=
0x20
;
/* ... turn off DCRT bit */
pc
->
buf
[
3
]
=
8
;
buf
[
3
]
=
8
;
put_unaligned
(
cpu_to_be32
(
b
),
(
unsigned
int
*
)(
&
pc
->
buf
[
4
]));
put_unaligned
(
cpu_to_be32
(
b
),
(
unsigned
int
*
)(
&
buf
[
4
]));
put_unaligned
(
cpu_to_be32
(
l
),
(
unsigned
int
*
)(
&
pc
->
buf
[
8
]));
put_unaligned
(
cpu_to_be32
(
l
),
(
unsigned
int
*
)(
&
buf
[
8
]));
pc
->
buf_size
=
12
;
pc
->
req_xfer
=
12
;
pc
->
flags
|=
PC_FLAG_WRITING
;
pc
->
flags
|=
PC_FLAG_WRITING
;
}
}
static
int
ide_floppy_get_sfrp_bit
(
ide_drive_t
*
drive
,
struct
ide_atapi_pc
*
pc
)
static
int
ide_floppy_get_sfrp_bit
(
ide_drive_t
*
drive
,
struct
ide_atapi_pc
*
pc
)
{
{
struct
ide_disk_obj
*
floppy
=
drive
->
driver_data
;
struct
ide_disk_obj
*
floppy
=
drive
->
driver_data
;
u8
buf
[
20
];
drive
->
atapi_flags
&=
~
IDE_AFLAG_SRFP
;
drive
->
atapi_flags
&=
~
IDE_AFLAG_SRFP
;
ide_floppy_create_mode_sense_cmd
(
pc
,
IDEFLOPPY_CAPABILITIES_PAGE
);
ide_floppy_create_mode_sense_cmd
(
pc
,
IDEFLOPPY_CAPABILITIES_PAGE
);
pc
->
flags
|=
PC_FLAG_SUPPRESS_ERROR
;
pc
->
flags
|=
PC_FLAG_SUPPRESS_ERROR
;
if
(
ide_queue_pc_tail
(
drive
,
floppy
->
disk
,
pc
))
if
(
ide_queue_pc_tail
(
drive
,
floppy
->
disk
,
pc
,
buf
,
pc
->
req_xfer
))
return
1
;
return
1
;
if
(
pc
->
buf
[
8
+
2
]
&
0x40
)
if
(
buf
[
8
+
2
]
&
0x40
)
drive
->
atapi_flags
|=
IDE_AFLAG_SRFP
;
drive
->
atapi_flags
|=
IDE_AFLAG_SRFP
;
return
0
;
return
0
;
...
@@ -137,6 +137,7 @@ static int ide_floppy_format_unit(ide_drive_t *drive, struct ide_atapi_pc *pc,
...
@@ -137,6 +137,7 @@ static int ide_floppy_format_unit(ide_drive_t *drive, struct ide_atapi_pc *pc,
int
__user
*
arg
)
int
__user
*
arg
)
{
{
struct
ide_disk_obj
*
floppy
=
drive
->
driver_data
;
struct
ide_disk_obj
*
floppy
=
drive
->
driver_data
;
u8
buf
[
12
];
int
blocks
,
length
,
flags
,
err
=
0
;
int
blocks
,
length
,
flags
,
err
=
0
;
if
(
floppy
->
openers
>
1
)
{
if
(
floppy
->
openers
>
1
)
{
...
@@ -170,9 +171,9 @@ static int ide_floppy_format_unit(ide_drive_t *drive, struct ide_atapi_pc *pc,
...
@@ -170,9 +171,9 @@ static int ide_floppy_format_unit(ide_drive_t *drive, struct ide_atapi_pc *pc,
}
}
ide_floppy_get_sfrp_bit
(
drive
,
pc
);
ide_floppy_get_sfrp_bit
(
drive
,
pc
);
ide_floppy_create_format_unit_cmd
(
pc
,
blocks
,
length
,
flags
);
ide_floppy_create_format_unit_cmd
(
pc
,
b
uf
,
b
locks
,
length
,
flags
);
if
(
ide_queue_pc_tail
(
drive
,
floppy
->
disk
,
pc
))
if
(
ide_queue_pc_tail
(
drive
,
floppy
->
disk
,
pc
,
buf
,
pc
->
req_xfer
))
err
=
-
EIO
;
err
=
-
EIO
;
out:
out:
...
@@ -196,11 +197,13 @@ static int ide_floppy_get_format_progress(ide_drive_t *drive,
...
@@ -196,11 +197,13 @@ static int ide_floppy_get_format_progress(ide_drive_t *drive,
int
__user
*
arg
)
int
__user
*
arg
)
{
{
struct
ide_disk_obj
*
floppy
=
drive
->
driver_data
;
struct
ide_disk_obj
*
floppy
=
drive
->
driver_data
;
u8
sense_buf
[
18
];
int
progress_indication
=
0x10000
;
int
progress_indication
=
0x10000
;
if
(
drive
->
atapi_flags
&
IDE_AFLAG_SRFP
)
{
if
(
drive
->
atapi_flags
&
IDE_AFLAG_SRFP
)
{
ide_create_request_sense_cmd
(
drive
,
pc
);
ide_create_request_sense_cmd
(
drive
,
pc
);
if
(
ide_queue_pc_tail
(
drive
,
floppy
->
disk
,
pc
))
if
(
ide_queue_pc_tail
(
drive
,
floppy
->
disk
,
pc
,
sense_buf
,
pc
->
req_xfer
))
return
-
EIO
;
return
-
EIO
;
if
(
floppy
->
sense_key
==
2
&&
if
(
floppy
->
sense_key
==
2
&&
...
...
drivers/ide/ide-tape.c
View file @
8dcce408
...
@@ -279,10 +279,12 @@ static void ide_tape_put(struct ide_tape_obj *tape)
...
@@ -279,10 +279,12 @@ static void ide_tape_put(struct ide_tape_obj *tape)
* called on each failed packet command retry to analyze the request sense. We
* called on each failed packet command retry to analyze the request sense. We
* currently do not utilize this information.
* currently do not utilize this information.
*/
*/
static
void
idetape_analyze_error
(
ide_drive_t
*
drive
,
u8
*
sense
)
static
void
idetape_analyze_error
(
ide_drive_t
*
drive
)
{
{
idetape_tape_t
*
tape
=
drive
->
driver_data
;
idetape_tape_t
*
tape
=
drive
->
driver_data
;
struct
ide_atapi_pc
*
pc
=
drive
->
failed_pc
;
struct
ide_atapi_pc
*
pc
=
drive
->
failed_pc
;
struct
request
*
rq
=
drive
->
hwif
->
rq
;
u8
*
sense
=
bio_data
(
rq
->
bio
);
tape
->
sense_key
=
sense
[
2
]
&
0xF
;
tape
->
sense_key
=
sense
[
2
]
&
0xF
;
tape
->
asc
=
sense
[
12
];
tape
->
asc
=
sense
[
12
];
...
@@ -291,11 +293,9 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense)
...
@@ -291,11 +293,9 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense)
debug_log
(
DBG_ERR
,
"pc = %x, sense key = %x, asc = %x, ascq = %x
\n
"
,
debug_log
(
DBG_ERR
,
"pc = %x, sense key = %x, asc = %x, ascq = %x
\n
"
,
pc
->
c
[
0
],
tape
->
sense_key
,
tape
->
asc
,
tape
->
ascq
);
pc
->
c
[
0
],
tape
->
sense_key
,
tape
->
asc
,
tape
->
ascq
);
/*
Correct pc->xferred by asking the tape.
*/
/*
correct remaining bytes to transfer
*/
if
(
pc
->
flags
&
PC_FLAG_DMA_ERROR
)
if
(
pc
->
flags
&
PC_FLAG_DMA_ERROR
)
pc
->
xferred
=
pc
->
req_xfer
-
rq
->
resid_len
=
tape
->
blk_size
*
get_unaligned_be32
(
&
sense
[
3
]);
tape
->
blk_size
*
get_unaligned_be32
(
&
sense
[
3
]);
/*
/*
* If error was the result of a zero-length read or write command,
* If error was the result of a zero-length read or write command,
...
@@ -329,7 +329,7 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense)
...
@@ -329,7 +329,7 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense)
pc
->
flags
|=
PC_FLAG_ABORT
;
pc
->
flags
|=
PC_FLAG_ABORT
;
}
}
if
(
!
(
pc
->
flags
&
PC_FLAG_ABORT
)
&&
if
(
!
(
pc
->
flags
&
PC_FLAG_ABORT
)
&&
pc
->
xferred
)
(
blk_rq_bytes
(
rq
)
-
rq
->
resid_len
)
)
pc
->
retries
=
IDETAPE_MAX_PC_RETRIES
+
1
;
pc
->
retries
=
IDETAPE_MAX_PC_RETRIES
+
1
;
}
}
}
}
...
@@ -354,12 +354,13 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc)
...
@@ -354,12 +354,13 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc)
if
(
pc
->
c
[
0
]
==
REQUEST_SENSE
)
{
if
(
pc
->
c
[
0
]
==
REQUEST_SENSE
)
{
if
(
uptodate
)
if
(
uptodate
)
idetape_analyze_error
(
drive
,
pc
->
buf
);
idetape_analyze_error
(
drive
);
else
else
printk
(
KERN_ERR
"ide-tape: Error in REQUEST SENSE "
printk
(
KERN_ERR
"ide-tape: Error in REQUEST SENSE "
"itself - Aborting request!
\n
"
);
"itself - Aborting request!
\n
"
);
}
else
if
(
pc
->
c
[
0
]
==
READ_6
||
pc
->
c
[
0
]
==
WRITE_6
)
{
}
else
if
(
pc
->
c
[
0
]
==
READ_6
||
pc
->
c
[
0
]
==
WRITE_6
)
{
int
blocks
=
pc
->
xferred
/
tape
->
blk_size
;
unsigned
int
blocks
=
(
blk_rq_bytes
(
rq
)
-
rq
->
resid_len
)
/
tape
->
blk_size
;
tape
->
avg_size
+=
blocks
*
tape
->
blk_size
;
tape
->
avg_size
+=
blocks
*
tape
->
blk_size
;
...
@@ -371,38 +372,12 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc)
...
@@ -371,38 +372,12 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc)
}
}
tape
->
first_frame
+=
blocks
;
tape
->
first_frame
+=
blocks
;
rq
->
resid_len
-=
blocks
*
tape
->
blk_size
;
if
(
pc
->
error
)
{
if
(
pc
->
error
)
{
uptodate
=
0
;
uptodate
=
0
;
err
=
pc
->
error
;
err
=
pc
->
error
;
}
}
}
else
if
(
pc
->
c
[
0
]
==
READ_POSITION
&&
uptodate
)
{
u8
*
readpos
=
pc
->
buf
;
debug_log
(
DBG_SENSE
,
"BOP - %s
\n
"
,
(
readpos
[
0
]
&
0x80
)
?
"Yes"
:
"No"
);
debug_log
(
DBG_SENSE
,
"EOP - %s
\n
"
,
(
readpos
[
0
]
&
0x40
)
?
"Yes"
:
"No"
);
if
(
readpos
[
0
]
&
0x4
)
{
printk
(
KERN_INFO
"ide-tape: Block location is unknown"
"to the tape
\n
"
);
clear_bit
(
ilog2
(
IDE_AFLAG_ADDRESS_VALID
),
&
drive
->
atapi_flags
);
uptodate
=
0
;
err
=
IDE_DRV_ERROR_GENERAL
;
}
else
{
debug_log
(
DBG_SENSE
,
"Block Location - %u
\n
"
,
be32_to_cpup
((
__be32
*
)
&
readpos
[
4
]));
tape
->
partition
=
readpos
[
1
];
tape
->
first_frame
=
be32_to_cpup
((
__be32
*
)
&
readpos
[
4
]);
set_bit
(
ilog2
(
IDE_AFLAG_ADDRESS_VALID
),
&
drive
->
atapi_flags
);
}
}
}
rq
->
errors
=
err
;
rq
->
errors
=
err
;
return
uptodate
;
return
uptodate
;
...
@@ -477,6 +452,7 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive,
...
@@ -477,6 +452,7 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive,
struct
ide_atapi_pc
*
pc
)
struct
ide_atapi_pc
*
pc
)
{
{
idetape_tape_t
*
tape
=
drive
->
driver_data
;
idetape_tape_t
*
tape
=
drive
->
driver_data
;
struct
request
*
rq
=
drive
->
hwif
->
rq
;
if
(
drive
->
failed_pc
==
NULL
&&
pc
->
c
[
0
]
!=
REQUEST_SENSE
)
if
(
drive
->
failed_pc
==
NULL
&&
pc
->
c
[
0
]
!=
REQUEST_SENSE
)
drive
->
failed_pc
=
pc
;
drive
->
failed_pc
=
pc
;
...
@@ -486,7 +462,6 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive,
...
@@ -486,7 +462,6 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive,
if
(
pc
->
retries
>
IDETAPE_MAX_PC_RETRIES
||
if
(
pc
->
retries
>
IDETAPE_MAX_PC_RETRIES
||
(
pc
->
flags
&
PC_FLAG_ABORT
))
{
(
pc
->
flags
&
PC_FLAG_ABORT
))
{
unsigned
int
done
=
blk_rq_bytes
(
drive
->
hwif
->
rq
);
/*
/*
* We will "abort" retrying a packet command in case legitimate
* We will "abort" retrying a packet command in case legitimate
...
@@ -510,7 +485,7 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive,
...
@@ -510,7 +485,7 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive,
drive
->
failed_pc
=
NULL
;
drive
->
failed_pc
=
NULL
;
drive
->
pc_callback
(
drive
,
0
);
drive
->
pc_callback
(
drive
,
0
);
ide_complete_rq
(
drive
,
-
EIO
,
done
);
ide_complete_rq
(
drive
,
-
EIO
,
blk_rq_bytes
(
rq
)
);
return
ide_stopped
;
return
ide_stopped
;
}
}
debug_log
(
DBG_SENSE
,
"Retry #%d, cmd = %02X
\n
"
,
pc
->
retries
,
pc
->
c
[
0
]);
debug_log
(
DBG_SENSE
,
"Retry #%d, cmd = %02X
\n
"
,
pc
->
retries
,
pc
->
c
[
0
]);
...
@@ -579,15 +554,13 @@ static void ide_tape_create_rw_cmd(idetape_tape_t *tape,
...
@@ -579,15 +554,13 @@ static void ide_tape_create_rw_cmd(idetape_tape_t *tape,
struct
ide_atapi_pc
*
pc
,
struct
request
*
rq
,
struct
ide_atapi_pc
*
pc
,
struct
request
*
rq
,
u8
opcode
)
u8
opcode
)
{
{
unsigned
int
length
=
blk_rq_sectors
(
rq
);
unsigned
int
length
=
blk_rq_sectors
(
rq
)
/
(
tape
->
blk_size
>>
9
)
;
ide_init_pc
(
pc
);
ide_init_pc
(
pc
);
put_unaligned
(
cpu_to_be32
(
length
),
(
unsigned
int
*
)
&
pc
->
c
[
1
]);
put_unaligned
(
cpu_to_be32
(
length
),
(
unsigned
int
*
)
&
pc
->
c
[
1
]);
pc
->
c
[
1
]
=
1
;
pc
->
c
[
1
]
=
1
;
pc
->
buf
=
NULL
;
pc
->
buf_size
=
length
*
tape
->
blk_size
;
if
(
blk_rq_bytes
(
rq
)
==
tape
->
buffer_size
)
pc
->
req_xfer
=
pc
->
buf_size
;
if
(
pc
->
req_xfer
==
tape
->
buffer_size
)
pc
->
flags
|=
PC_FLAG_DMA_OK
;
pc
->
flags
|=
PC_FLAG_DMA_OK
;
if
(
opcode
==
READ_6
)
if
(
opcode
==
READ_6
)
...
@@ -713,7 +686,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
...
@@ -713,7 +686,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
cmd
.
rq
=
rq
;
cmd
.
rq
=
rq
;
ide_init_sg_cmd
(
&
cmd
,
pc
->
req_xfer
);
ide_init_sg_cmd
(
&
cmd
,
blk_rq_bytes
(
rq
)
);
ide_map_sg
(
drive
,
&
cmd
);
ide_map_sg
(
drive
,
&
cmd
);
return
ide_tape_issue_pc
(
drive
,
&
cmd
,
pc
);
return
ide_tape_issue_pc
(
drive
,
&
cmd
,
pc
);
...
@@ -767,33 +740,53 @@ static int idetape_flush_tape_buffers(ide_drive_t *drive)
...
@@ -767,33 +740,53 @@ static int idetape_flush_tape_buffers(ide_drive_t *drive)
int
rc
;
int
rc
;
idetape_create_write_filemark_cmd
(
drive
,
&
pc
,
0
);
idetape_create_write_filemark_cmd
(
drive
,
&
pc
,
0
);
rc
=
ide_queue_pc_tail
(
drive
,
tape
->
disk
,
&
pc
);
rc
=
ide_queue_pc_tail
(
drive
,
tape
->
disk
,
&
pc
,
NULL
,
0
);
if
(
rc
)
if
(
rc
)
return
rc
;
return
rc
;
idetape_wait_ready
(
drive
,
60
*
5
*
HZ
);
idetape_wait_ready
(
drive
,
60
*
5
*
HZ
);
return
0
;
return
0
;
}
}
static
void
idetape_create_read_position_cmd
(
struct
ide_atapi_pc
*
pc
)
static
int
ide_tape_read_position
(
ide_drive_t
*
drive
)
{
ide_init_pc
(
pc
);
pc
->
c
[
0
]
=
READ_POSITION
;
pc
->
req_xfer
=
20
;
}
static
int
idetape_read_position
(
ide_drive_t
*
drive
)
{
{
idetape_tape_t
*
tape
=
drive
->
driver_data
;
idetape_tape_t
*
tape
=
drive
->
driver_data
;
struct
ide_atapi_pc
pc
;
struct
ide_atapi_pc
pc
;
int
position
;
u8
buf
[
20
]
;
debug_log
(
DBG_PROCS
,
"Enter %s
\n
"
,
__func__
);
debug_log
(
DBG_PROCS
,
"Enter %s
\n
"
,
__func__
);
idetape_create_read_position_cmd
(
&
pc
);
/* prep cmd */
if
(
ide_queue_pc_tail
(
drive
,
tape
->
disk
,
&
pc
))
ide_init_pc
(
&
pc
);
pc
.
c
[
0
]
=
READ_POSITION
;
pc
.
req_xfer
=
20
;
if
(
ide_queue_pc_tail
(
drive
,
tape
->
disk
,
&
pc
,
buf
,
pc
.
req_xfer
))
return
-
1
;
return
-
1
;
position
=
tape
->
first_frame
;
return
position
;
if
(
!
pc
.
error
)
{
debug_log
(
DBG_SENSE
,
"BOP - %s
\n
"
,
(
buf
[
0
]
&
0x80
)
?
"Yes"
:
"No"
);
debug_log
(
DBG_SENSE
,
"EOP - %s
\n
"
,
(
buf
[
0
]
&
0x40
)
?
"Yes"
:
"No"
);
if
(
buf
[
0
]
&
0x4
)
{
printk
(
KERN_INFO
"ide-tape: Block location is unknown"
"to the tape
\n
"
);
clear_bit
(
ilog2
(
IDE_AFLAG_ADDRESS_VALID
),
&
drive
->
atapi_flags
);
return
-
1
;
}
else
{
debug_log
(
DBG_SENSE
,
"Block Location - %u
\n
"
,
be32_to_cpup
((
__be32
*
)
&
buf
[
4
]));
tape
->
partition
=
buf
[
1
];
tape
->
first_frame
=
be32_to_cpup
((
__be32
*
)
&
buf
[
4
]);
set_bit
(
ilog2
(
IDE_AFLAG_ADDRESS_VALID
),
&
drive
->
atapi_flags
);
}
}
return
tape
->
first_frame
;
}
}
static
void
idetape_create_locate_cmd
(
ide_drive_t
*
drive
,
static
void
idetape_create_locate_cmd
(
ide_drive_t
*
drive
,
...
@@ -836,19 +829,21 @@ static int idetape_position_tape(ide_drive_t *drive, unsigned int block,
...
@@ -836,19 +829,21 @@ static int idetape_position_tape(ide_drive_t *drive, unsigned int block,
{
{
idetape_tape_t
*
tape
=
drive
->
driver_data
;
idetape_tape_t
*
tape
=
drive
->
driver_data
;
struct
gendisk
*
disk
=
tape
->
disk
;
struct
gendisk
*
disk
=
tape
->
disk
;
int
ret
val
;
int
ret
;
struct
ide_atapi_pc
pc
;
struct
ide_atapi_pc
pc
;
if
(
tape
->
chrdev_dir
==
IDETAPE_DIR_READ
)
if
(
tape
->
chrdev_dir
==
IDETAPE_DIR_READ
)
__ide_tape_discard_merge_buffer
(
drive
);
__ide_tape_discard_merge_buffer
(
drive
);
idetape_wait_ready
(
drive
,
60
*
5
*
HZ
);
idetape_wait_ready
(
drive
,
60
*
5
*
HZ
);
idetape_create_locate_cmd
(
drive
,
&
pc
,
block
,
partition
,
skip
);
idetape_create_locate_cmd
(
drive
,
&
pc
,
block
,
partition
,
skip
);
ret
val
=
ide_queue_pc_tail
(
drive
,
disk
,
&
pc
);
ret
=
ide_queue_pc_tail
(
drive
,
disk
,
&
pc
,
NULL
,
0
);
if
(
ret
val
)
if
(
ret
)
return
(
retval
)
;
return
ret
;
idetape_create_read_position_cmd
(
&
pc
);
ret
=
ide_tape_read_position
(
drive
);
return
ide_queue_pc_tail
(
drive
,
disk
,
&
pc
);
if
(
ret
<
0
)
return
ret
;
return
0
;
}
}
static
void
ide_tape_discard_merge_buffer
(
ide_drive_t
*
drive
,
static
void
ide_tape_discard_merge_buffer
(
ide_drive_t
*
drive
,
...
@@ -859,7 +854,7 @@ static void ide_tape_discard_merge_buffer(ide_drive_t *drive,
...
@@ -859,7 +854,7 @@ static void ide_tape_discard_merge_buffer(ide_drive_t *drive,
__ide_tape_discard_merge_buffer
(
drive
);
__ide_tape_discard_merge_buffer
(
drive
);
if
(
restore_position
)
{
if
(
restore_position
)
{
position
=
idetape_read_position
(
drive
);
position
=
ide
_
tape_read_position
(
drive
);
seek
=
position
>
0
?
position
:
0
;
seek
=
position
>
0
?
position
:
0
;
if
(
idetape_position_tape
(
drive
,
seek
,
0
,
0
))
{
if
(
idetape_position_tape
(
drive
,
seek
,
0
,
0
))
{
printk
(
KERN_INFO
"ide-tape: %s: position_tape failed in"
printk
(
KERN_INFO
"ide-tape: %s: position_tape failed in"
...
@@ -1039,20 +1034,19 @@ static int idetape_rewind_tape(ide_drive_t *drive)
...
@@ -1039,20 +1034,19 @@ static int idetape_rewind_tape(ide_drive_t *drive)
{
{
struct
ide_tape_obj
*
tape
=
drive
->
driver_data
;
struct
ide_tape_obj
*
tape
=
drive
->
driver_data
;
struct
gendisk
*
disk
=
tape
->
disk
;
struct
gendisk
*
disk
=
tape
->
disk
;
int
retval
;
struct
ide_atapi_pc
pc
;
struct
ide_atapi_pc
pc
;
int
ret
;
debug_log
(
DBG_SENSE
,
"Enter %s
\n
"
,
__func__
);
debug_log
(
DBG_SENSE
,
"Enter %s
\n
"
,
__func__
);
idetape_create_rewind_cmd
(
drive
,
&
pc
);
idetape_create_rewind_cmd
(
drive
,
&
pc
);
ret
val
=
ide_queue_pc_tail
(
drive
,
disk
,
&
pc
);
ret
=
ide_queue_pc_tail
(
drive
,
disk
,
&
pc
,
NULL
,
0
);
if
(
ret
val
)
if
(
ret
)
return
ret
val
;
return
ret
;
idetape_create_read_position_cmd
(
&
pc
);
ret
=
ide_tape_read_position
(
drive
);
retval
=
ide_queue_pc_tail
(
drive
,
disk
,
&
pc
);
if
(
ret
<
0
)
if
(
retval
)
return
ret
;
return
retval
;
return
0
;
return
0
;
}
}
...
@@ -1119,7 +1113,7 @@ static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op,
...
@@ -1119,7 +1113,7 @@ static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op,
case
MTBSF
:
case
MTBSF
:
idetape_create_space_cmd
(
&
pc
,
mt_count
-
count
,
idetape_create_space_cmd
(
&
pc
,
mt_count
-
count
,
IDETAPE_SPACE_OVER_FILEMARK
);
IDETAPE_SPACE_OVER_FILEMARK
);
return
ide_queue_pc_tail
(
drive
,
disk
,
&
pc
);
return
ide_queue_pc_tail
(
drive
,
disk
,
&
pc
,
NULL
,
0
);
case
MTFSFM
:
case
MTFSFM
:
case
MTBSFM
:
case
MTBSFM
:
if
(
!
sprev
)
if
(
!
sprev
)
...
@@ -1259,7 +1253,7 @@ static int idetape_write_filemark(ide_drive_t *drive)
...
@@ -1259,7 +1253,7 @@ static int idetape_write_filemark(ide_drive_t *drive)
/* Write a filemark */
/* Write a filemark */
idetape_create_write_filemark_cmd
(
drive
,
&
pc
,
1
);
idetape_create_write_filemark_cmd
(
drive
,
&
pc
,
1
);
if
(
ide_queue_pc_tail
(
drive
,
tape
->
disk
,
&
pc
))
{
if
(
ide_queue_pc_tail
(
drive
,
tape
->
disk
,
&
pc
,
NULL
,
0
))
{
printk
(
KERN_ERR
"ide-tape: Couldn't write a filemark
\n
"
);
printk
(
KERN_ERR
"ide-tape: Couldn't write a filemark
\n
"
);
return
-
EIO
;
return
-
EIO
;
}
}
...
@@ -1345,11 +1339,11 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
...
@@ -1345,11 +1339,11 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
IDETAPE_LU_RETENSION_MASK
|
IDETAPE_LU_LOAD_MASK
);
IDETAPE_LU_RETENSION_MASK
|
IDETAPE_LU_LOAD_MASK
);
case
MTEOM
:
case
MTEOM
:
idetape_create_space_cmd
(
&
pc
,
0
,
IDETAPE_SPACE_TO_EOD
);
idetape_create_space_cmd
(
&
pc
,
0
,
IDETAPE_SPACE_TO_EOD
);
return
ide_queue_pc_tail
(
drive
,
disk
,
&
pc
);
return
ide_queue_pc_tail
(
drive
,
disk
,
&
pc
,
NULL
,
0
);
case
MTERASE
:
case
MTERASE
:
(
void
)
idetape_rewind_tape
(
drive
);
(
void
)
idetape_rewind_tape
(
drive
);
idetape_create_erase_cmd
(
&
pc
);
idetape_create_erase_cmd
(
&
pc
);
return
ide_queue_pc_tail
(
drive
,
disk
,
&
pc
);
return
ide_queue_pc_tail
(
drive
,
disk
,
&
pc
,
NULL
,
0
);
case
MTSETBLK
:
case
MTSETBLK
:
if
(
mt_count
)
{
if
(
mt_count
)
{
if
(
mt_count
<
tape
->
blk_size
||
if
(
mt_count
<
tape
->
blk_size
||
...
@@ -1415,7 +1409,7 @@ static int idetape_chrdev_ioctl(struct inode *inode, struct file *file,
...
@@ -1415,7 +1409,7 @@ static int idetape_chrdev_ioctl(struct inode *inode, struct file *file,
if
(
cmd
==
MTIOCGET
||
cmd
==
MTIOCPOS
)
{
if
(
cmd
==
MTIOCGET
||
cmd
==
MTIOCPOS
)
{
block_offset
=
tape
->
valid
/
block_offset
=
tape
->
valid
/
(
tape
->
blk_size
*
tape
->
user_bs_factor
);
(
tape
->
blk_size
*
tape
->
user_bs_factor
);
position
=
idetape_read_position
(
drive
);
position
=
ide
_
tape_read_position
(
drive
);
if
(
position
<
0
)
if
(
position
<
0
)
return
-
EIO
;
return
-
EIO
;
}
}
...
@@ -1458,9 +1452,10 @@ static void ide_tape_get_bsize_from_bdesc(ide_drive_t *drive)
...
@@ -1458,9 +1452,10 @@ static void ide_tape_get_bsize_from_bdesc(ide_drive_t *drive)
{
{
idetape_tape_t
*
tape
=
drive
->
driver_data
;
idetape_tape_t
*
tape
=
drive
->
driver_data
;
struct
ide_atapi_pc
pc
;
struct
ide_atapi_pc
pc
;
u8
buf
[
12
];
idetape_create_mode_sense_cmd
(
&
pc
,
IDETAPE_BLOCK_DESCRIPTOR
);
idetape_create_mode_sense_cmd
(
&
pc
,
IDETAPE_BLOCK_DESCRIPTOR
);
if
(
ide_queue_pc_tail
(
drive
,
tape
->
disk
,
&
pc
))
{
if
(
ide_queue_pc_tail
(
drive
,
tape
->
disk
,
&
pc
,
buf
,
pc
.
req_xfer
))
{
printk
(
KERN_ERR
"ide-tape: Can't get block descriptor
\n
"
);
printk
(
KERN_ERR
"ide-tape: Can't get block descriptor
\n
"
);
if
(
tape
->
blk_size
==
0
)
{
if
(
tape
->
blk_size
==
0
)
{
printk
(
KERN_WARNING
"ide-tape: Cannot deal with zero "
printk
(
KERN_WARNING
"ide-tape: Cannot deal with zero "
...
@@ -1469,10 +1464,10 @@ static void ide_tape_get_bsize_from_bdesc(ide_drive_t *drive)
...
@@ -1469,10 +1464,10 @@ static void ide_tape_get_bsize_from_bdesc(ide_drive_t *drive)
}
}
return
;
return
;
}
}
tape
->
blk_size
=
(
pc
.
buf
[
4
+
5
]
<<
16
)
+
tape
->
blk_size
=
(
buf
[
4
+
5
]
<<
16
)
+
(
pc
.
buf
[
4
+
6
]
<<
8
)
+
(
buf
[
4
+
6
]
<<
8
)
+
pc
.
buf
[
4
+
7
];
buf
[
4
+
7
];
tape
->
drv_write_prot
=
(
pc
.
buf
[
2
]
&
0x80
)
>>
7
;
tape
->
drv_write_prot
=
(
buf
[
2
]
&
0x80
)
>>
7
;
}
}
static
int
idetape_chrdev_open
(
struct
inode
*
inode
,
struct
file
*
filp
)
static
int
idetape_chrdev_open
(
struct
inode
*
inode
,
struct
file
*
filp
)
...
@@ -1615,17 +1610,14 @@ static void idetape_get_inquiry_results(ide_drive_t *drive)
...
@@ -1615,17 +1610,14 @@ static void idetape_get_inquiry_results(ide_drive_t *drive)
char
fw_rev
[
4
],
vendor_id
[
8
],
product_id
[
16
];
char
fw_rev
[
4
],
vendor_id
[
8
],
product_id
[
16
];
idetape_create_inquiry_cmd
(
&
pc
);
idetape_create_inquiry_cmd
(
&
pc
);
pc
.
buf
=
&
pc_buf
[
0
];
if
(
ide_queue_pc_tail
(
drive
,
tape
->
disk
,
&
pc
,
pc_buf
,
pc
.
req_xfer
))
{
pc
.
buf_size
=
sizeof
(
pc_buf
);
if
(
ide_queue_pc_tail
(
drive
,
tape
->
disk
,
&
pc
))
{
printk
(
KERN_ERR
"ide-tape: %s: can't get INQUIRY results
\n
"
,
printk
(
KERN_ERR
"ide-tape: %s: can't get INQUIRY results
\n
"
,
tape
->
name
);
tape
->
name
);
return
;
return
;
}
}
memcpy
(
vendor_id
,
&
pc
.
buf
[
8
],
8
);
memcpy
(
vendor_id
,
&
pc
_
buf
[
8
],
8
);
memcpy
(
product_id
,
&
pc
.
buf
[
16
],
16
);
memcpy
(
product_id
,
&
pc
_
buf
[
16
],
16
);
memcpy
(
fw_rev
,
&
pc
.
buf
[
32
],
4
);
memcpy
(
fw_rev
,
&
pc
_
buf
[
32
],
4
);
ide_fixstring
(
vendor_id
,
8
,
0
);
ide_fixstring
(
vendor_id
,
8
,
0
);
ide_fixstring
(
product_id
,
16
,
0
);
ide_fixstring
(
product_id
,
16
,
0
);
...
@@ -1643,11 +1635,11 @@ static void idetape_get_mode_sense_results(ide_drive_t *drive)
...
@@ -1643,11 +1635,11 @@ static void idetape_get_mode_sense_results(ide_drive_t *drive)
{
{
idetape_tape_t
*
tape
=
drive
->
driver_data
;
idetape_tape_t
*
tape
=
drive
->
driver_data
;
struct
ide_atapi_pc
pc
;
struct
ide_atapi_pc
pc
;
u8
*
caps
;
u8
buf
[
24
],
*
caps
;
u8
speed
,
max_speed
;
u8
speed
,
max_speed
;
idetape_create_mode_sense_cmd
(
&
pc
,
IDETAPE_CAPABILITIES_PAGE
);
idetape_create_mode_sense_cmd
(
&
pc
,
IDETAPE_CAPABILITIES_PAGE
);
if
(
ide_queue_pc_tail
(
drive
,
tape
->
disk
,
&
pc
))
{
if
(
ide_queue_pc_tail
(
drive
,
tape
->
disk
,
&
pc
,
buf
,
pc
.
req_xfer
))
{
printk
(
KERN_ERR
"ide-tape: Can't get tape parameters - assuming"
printk
(
KERN_ERR
"ide-tape: Can't get tape parameters - assuming"
" some default values
\n
"
);
" some default values
\n
"
);
tape
->
blk_size
=
512
;
tape
->
blk_size
=
512
;
...
@@ -1656,7 +1648,7 @@ static void idetape_get_mode_sense_results(ide_drive_t *drive)
...
@@ -1656,7 +1648,7 @@ static void idetape_get_mode_sense_results(ide_drive_t *drive)
put_unaligned
(
6
*
52
,
(
u16
*
)
&
tape
->
caps
[
16
]);
put_unaligned
(
6
*
52
,
(
u16
*
)
&
tape
->
caps
[
16
]);
return
;
return
;
}
}
caps
=
pc
.
buf
+
4
+
pc
.
buf
[
3
];
caps
=
buf
+
4
+
buf
[
3
];
/* convert to host order and save for later use */
/* convert to host order and save for later use */
speed
=
be16_to_cpup
((
__be16
*
)
&
caps
[
14
]);
speed
=
be16_to_cpup
((
__be16
*
)
&
caps
[
14
]);
...
...
include/linux/ide.h
View file @
8dcce408
...
@@ -331,11 +331,6 @@ enum {
...
@@ -331,11 +331,6 @@ enum {
PC_FLAG_WRITING
=
(
1
<<
6
),
PC_FLAG_WRITING
=
(
1
<<
6
),
};
};
/*
* With each packet command, we allocate a buffer of IDE_PC_BUFFER_SIZE bytes.
* This is used for several packet commands (not for READ/WRITE commands).
*/
#define IDE_PC_BUFFER_SIZE 64
#define ATAPI_WAIT_PC (60 * HZ)
#define ATAPI_WAIT_PC (60 * HZ)
struct
ide_atapi_pc
{
struct
ide_atapi_pc
{
...
@@ -347,12 +342,6 @@ struct ide_atapi_pc {
...
@@ -347,12 +342,6 @@ struct ide_atapi_pc {
/* bytes to transfer */
/* bytes to transfer */
int
req_xfer
;
int
req_xfer
;
/* bytes actually transferred */
int
xferred
;
/* data buffer */
u8
*
buf
;
int
buf_size
;
/* the corresponding request */
/* the corresponding request */
struct
request
*
rq
;
struct
request
*
rq
;
...
@@ -363,8 +352,6 @@ struct ide_atapi_pc {
...
@@ -363,8 +352,6 @@ struct ide_atapi_pc {
* those are more or less driver-specific and some of them are subject
* those are more or less driver-specific and some of them are subject
* to change/removal later.
* to change/removal later.
*/
*/
u8
pc_buf
[
IDE_PC_BUFFER_SIZE
];
unsigned
long
timeout
;
unsigned
long
timeout
;
};
};
...
@@ -1130,6 +1117,8 @@ void SELECT_MASK(ide_drive_t *, int);
...
@@ -1130,6 +1117,8 @@ void SELECT_MASK(ide_drive_t *, int);
u8
ide_read_error
(
ide_drive_t
*
);
u8
ide_read_error
(
ide_drive_t
*
);
void
ide_read_bcount_and_ireason
(
ide_drive_t
*
,
u16
*
,
u8
*
);
void
ide_read_bcount_and_ireason
(
ide_drive_t
*
,
u16
*
,
u8
*
);
int
ide_check_ireason
(
ide_drive_t
*
,
struct
request
*
,
int
,
int
,
int
);
int
ide_check_atapi_device
(
ide_drive_t
*
,
const
char
*
);
int
ide_check_atapi_device
(
ide_drive_t
*
,
const
char
*
);
void
ide_init_pc
(
struct
ide_atapi_pc
*
);
void
ide_init_pc
(
struct
ide_atapi_pc
*
);
...
@@ -1154,7 +1143,8 @@ enum {
...
@@ -1154,7 +1143,8 @@ enum {
REQ_IDETAPE_WRITE
=
(
1
<<
3
),
REQ_IDETAPE_WRITE
=
(
1
<<
3
),
};
};
int
ide_queue_pc_tail
(
ide_drive_t
*
,
struct
gendisk
*
,
struct
ide_atapi_pc
*
);
int
ide_queue_pc_tail
(
ide_drive_t
*
,
struct
gendisk
*
,
struct
ide_atapi_pc
*
,
void
*
,
unsigned
int
);
int
ide_do_test_unit_ready
(
ide_drive_t
*
,
struct
gendisk
*
);
int
ide_do_test_unit_ready
(
ide_drive_t
*
,
struct
gendisk
*
);
int
ide_do_start_stop
(
ide_drive_t
*
,
struct
gendisk
*
,
int
);
int
ide_do_start_stop
(
ide_drive_t
*
,
struct
gendisk
*
,
int
);
...
...
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