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
Show 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 @@
#include <scsi/scsi.h>
#define DRV_NAME "ide-atapi"
#define PFX DRV_NAME ": "
#ifdef DEBUG
#define debug_log(fmt, args...) \
printk(KERN_INFO "ide: " fmt, ## args)
...
...
@@ -74,8 +77,6 @@ EXPORT_SYMBOL_GPL(ide_check_atapi_device);
void
ide_init_pc
(
struct
ide_atapi_pc
*
pc
)
{
memset
(
pc
,
0
,
sizeof
(
*
pc
));
pc
->
buf
=
pc
->
pc_buf
;
pc
->
buf_size
=
IDE_PC_BUFFER_SIZE
;
}
EXPORT_SYMBOL_GPL
(
ide_init_pc
);
...
...
@@ -84,7 +85,7 @@ EXPORT_SYMBOL_GPL(ide_init_pc);
* and wait for it to be serviced.
*/
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
;
int
error
;
...
...
@@ -93,8 +94,8 @@ int ide_queue_pc_tail(ide_drive_t *drive, struct gendisk *disk,
rq
->
cmd_type
=
REQ_TYPE_SPECIAL
;
rq
->
special
=
(
char
*
)
pc
;
if
(
pc
->
req_xfer
)
{
error
=
blk_rq_map_kern
(
drive
->
queue
,
rq
,
pc
->
buf
,
pc
->
req_xfer
,
if
(
buf
&&
bufflen
)
{
error
=
blk_rq_map_kern
(
drive
->
queue
,
rq
,
buf
,
bufflen
,
GFP_NOIO
);
if
(
error
)
goto
put_req
;
...
...
@@ -117,7 +118,7 @@ int ide_do_test_unit_ready(ide_drive_t *drive, struct gendisk *disk)
ide_init_pc
(
&
pc
);
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
);
...
...
@@ -132,7 +133,7 @@ int ide_do_start_stop(ide_drive_t *drive, struct gendisk *disk, int start)
if
(
drive
->
media
==
ide_tape
)
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
);
...
...
@@ -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
[
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
);
...
...
@@ -172,8 +173,6 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq)
unsigned
int
cmd_len
,
sense_len
;
int
err
;
debug_log
(
"%s: enter
\n
"
,
__func__
);
switch
(
drive
->
media
)
{
case
ide_floppy
:
cmd_len
=
255
;
...
...
@@ -201,8 +200,8 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq)
GFP_NOIO
);
if
(
unlikely
(
err
))
{
if
(
printk_ratelimit
())
printk
(
KERN_WARNING
"%s: failed to map sense buffer
\n
"
,
drive
->
name
);
printk
(
KERN_WARNING
PFX
"%s: failed to map sense "
"buffer
\n
"
,
drive
->
name
);
return
;
}
...
...
@@ -223,7 +222,7 @@ int ide_queue_sense_rq(ide_drive_t *drive, void *special)
{
/* deferred failure from ide_prep_sense() */
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
);
return
-
ENOMEM
;
}
...
...
@@ -255,8 +254,6 @@ void ide_retry_pc(ide_drive_t *drive)
/* init pc from sense_rq */
ide_init_pc
(
pc
);
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
)
drive
->
atapi_flags
|=
IDE_AFLAG_IGNORE_DSC
;
...
...
@@ -298,7 +295,7 @@ int ide_cd_expiry(ide_drive_t *drive)
break
;
default:
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
]);
wait
=
0
;
break
;
...
...
@@ -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
);
/*
* 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
* 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)
if
(
rc
||
(
drive
->
media
==
ide_tape
&&
(
stat
&
ATA_ERR
)))
{
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
)
?
"write"
:
"read"
);
pc
->
flags
|=
PC_FLAG_DMA_ERROR
;
}
else
pc
->
xferred
=
pc
->
req_xfer
;
rq
->
resid_len
=
0
;
debug_log
(
"%s: DMA finished
\n
"
,
drive
->
name
);
}
...
...
@@ -379,7 +425,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
int
uptodate
,
error
;
debug_log
(
"Packet command completed, %d bytes transferred
\n
"
,
pc
->
xferred
);
blk_rq_bytes
(
rq
)
);
pc
->
flags
&=
~
PC_FLAG_DMA_IN_PROGRESS
;
...
...
@@ -397,8 +443,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
pc
->
rq
->
errors
++
;
if
(
rq
->
cmd
[
0
]
==
REQUEST_SENSE
)
{
printk
(
KERN_ERR
"%s: I/O error in request sense
"
" command
\n
"
,
drive
->
name
);
printk
(
KERN_ERR
PFX
"%s: I/O error in request
"
"
sense
command
\n
"
,
drive
->
name
);
return
ide_do_reset
(
drive
);
}
...
...
@@ -446,8 +492,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
if
(
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
"
"in DMA mode
\n
"
,
drive
->
name
);
printk
(
KERN_ERR
PFX
"%s: The device wants to issue more
"
"in
terrupts in
DMA mode
\n
"
,
drive
->
name
);
ide_dma_off
(
drive
);
return
ide_do_reset
(
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. */
ide_read_bcount_and_ireason
(
drive
,
&
bcount
,
&
ireason
);
if
(
ireason
&
ATAPI_COD
)
{
printk
(
KERN_ERR
"%s: CoD != 0 in %s
\n
"
,
drive
->
name
,
__func__
);
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"
);
if
(
ide_check_ireason
(
drive
,
rq
,
bcount
,
ireason
,
write
))
return
ide_do_reset
(
drive
);
}
done
=
min_t
(
unsigned
int
,
bcount
,
cmd
->
nleft
);
ide_pio_bytes
(
drive
,
cmd
,
write
,
done
);
/* Update transferred byte count */
pc
->
xferred
+
=
done
;
rq
->
resid_len
-
=
done
;
bcount
-=
done
;
if
(
bcount
)
ide_pad_transfer
(
drive
,
write
,
bcount
);
debug_log
(
"[cmd %x] transferred %d bytes, padded %d bytes
\n
"
,
rq
->
cmd
[
0
],
done
,
bcount
);
debug_log
(
"[cmd %x] transferred %d bytes, padded %d bytes
, resid: %u
\n
"
,
rq
->
cmd
[
0
],
done
,
bcount
,
rq
->
resid_len
);
/* And set the interrupt handler again */
ide_set_handler
(
drive
,
ide_pc_intr
,
timeout
);
...
...
@@ -515,13 +550,13 @@ static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason)
while
(
retries
--
&&
((
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 issuing "
"a packet command, retrying
\n
"
,
drive
->
name
);
udelay
(
100
);
ireason
=
ide_read_ireason
(
drive
);
if
(
retries
==
0
)
{
printk
(
KERN_ERR
"%s: (IO,CoD != (0,1) while issuing
"
"a packet command, ignoring
\n
"
,
printk
(
KERN_ERR
PFX
"%s: (IO,CoD != (0,1) while issuing
"
"
a packet command, ignoring
\n
"
,
drive
->
name
);
ireason
|=
ATAPI_COD
;
ireason
&=
~
ATAPI_IO
;
...
...
@@ -552,7 +587,7 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
u8
ireason
;
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
);
return
startstop
;
}
...
...
@@ -594,8 +629,8 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
ireason
=
ide_wait_ireason
(
drive
,
ireason
);
if
((
ireason
&
ATAPI_COD
)
==
0
||
(
ireason
&
ATAPI_IO
))
{
printk
(
KERN_ERR
"%s: (IO,CoD) != (0,1) while issuing
"
"
a packet command
\n
"
,
drive
->
name
);
printk
(
KERN_ERR
PFX
"%s: (IO,CoD) != (0,1) while
"
"issuing
a packet command
\n
"
,
drive
->
name
);
return
ide_do_reset
(
drive
);
}
...
...
@@ -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_expiry_t
*
expiry
=
NULL
;
struct
request
*
rq
=
hwif
->
rq
;
unsigned
int
timeout
;
unsigned
int
timeout
,
bytes
;
u16
bcount
;
u8
valid_tf
;
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)
}
else
{
pc
=
drive
->
pc
;
/* We haven't transferred any data yet */
pc
->
xferred
=
0
;
valid_tf
=
IDE_VALID_DEVICE
;
bcount
=
((
drive
->
media
==
ide_tape
)
?
pc
->
req_xfer
:
min
(
pc
->
req_xfer
,
63
*
1024
));
bytes
=
blk_rq_bytes
(
rq
);
bcount
=
((
drive
->
media
==
ide_tape
)
?
bytes
:
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
)
{
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)
drive
->
atapi_flags
&=
~
IDE_AFLAG_TOC_VALID
;
}
static
int
cdrom_log_sense
(
ide_drive_t
*
drive
,
struct
request
*
rq
,
struct
request_sense
*
sense
)
static
int
cdrom_log_sense
(
ide_drive_t
*
drive
,
struct
request
*
rq
)
{
struct
request_sense
*
sense
=
&
drive
->
sense_data
;
int
log
=
0
;
ide_debug_log
(
IDE_DBG_SENSE
,
"sense_key: 0x%x"
,
sense
->
sense_key
);
if
(
!
sense
||
!
rq
||
(
rq
->
cmd_flags
&
REQ_QUIET
))
return
0
;
ide_debug_log
(
IDE_DBG_SENSE
,
"sense_key: 0x%x"
,
sense
->
sense_key
);
switch
(
sense
->
sense_key
)
{
case
NO_SENSE
:
case
RECOVERED_ERROR
:
...
...
@@ -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
,
struct
request
*
failed_command
,
struct
request_sense
*
sense
)
struct
request
*
failed_command
)
{
struct
request_sense
*
sense
=
&
drive
->
sense_data
;
struct
cdrom_info
*
info
=
drive
->
driver_data
;
unsigned
long
sector
;
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"
,
sense
->
error_code
,
sense
->
sense_key
);
...
...
@@ -154,7 +154,7 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive,
ide_debug_log
(
IDE_DBG_SENSE
,
"failed cmd: 0x%x"
,
failed_command
->
cmd
[
0
]);
if
(
!
cdrom_log_sense
(
drive
,
failed_command
,
sense
))
if
(
!
cdrom_log_sense
(
drive
,
failed_command
))
return
;
/*
...
...
@@ -225,15 +225,14 @@ static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq)
* sense pointer set.
*/
memcpy
(
failed
->
sense
,
sense
,
18
);
sense
=
failed
->
sense
;
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
)))
BUG
();
}
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)
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
)
{
struct
request
*
rq
=
cmd
->
rq
;
...
...
@@ -645,8 +600,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
goto
out_end
;
}
/* check which way to transfer data */
rc
=
ide_cd_check_ireason
(
drive
,
rq
,
len
,
ireason
,
write
);
rc
=
ide_check_ireason
(
drive
,
rq
,
len
,
ireason
,
write
);
if
(
rc
)
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)
(
rq
&&
blk_pc_request
(
rq
)))
uptodate
=
1
;
/* FIXME */
else
if
(
pc
->
c
[
0
]
==
GPCMD_REQUEST_SENSE
)
{
u8
*
buf
=
pc
->
buf
;
u8
*
buf
=
bio_data
(
rq
->
bio
);
if
(
!
pc
->
error
)
{
floppy
->
sense_key
=
buf
[
2
]
&
0x0F
;
...
...
@@ -209,8 +210,7 @@ static void idefloppy_create_rw_cmd(ide_drive_t *drive,
pc
->
rq
=
rq
;
if
(
rq
->
cmd_flags
&
REQ_RW
)
pc
->
flags
|=
PC_FLAG_WRITING
;
pc
->
buf
=
NULL
;
pc
->
req_xfer
=
pc
->
buf_size
=
blocks
*
floppy
->
block_size
;
pc
->
flags
|=
PC_FLAG_DMA_OK
;
}
...
...
@@ -225,9 +225,6 @@ static void idefloppy_blockpc_cmd(struct ide_disk_obj *floppy,
if
(
rq_data_dir
(
rq
)
==
WRITE
)
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
,
...
...
@@ -286,8 +283,8 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
cmd
.
rq
=
rq
;
if
(
blk_fs_request
(
rq
)
||
pc
->
req_xfer
)
{
ide_init_sg_cmd
(
&
cmd
,
pc
->
req_xfer
);
if
(
blk_fs_request
(
rq
)
||
blk_rq_bytes
(
rq
)
)
{
ide_init_sg_cmd
(
&
cmd
,
blk_rq_bytes
(
rq
)
);
ide_map_sg
(
drive
,
&
cmd
);
}
...
...
@@ -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
gendisk
*
disk
=
floppy
->
disk
;
u8
*
page
;
u8
*
page
,
buf
[
40
]
;
int
capacity
,
lba_capacity
;
u16
transfer_rate
,
sector_size
,
cyls
,
rpm
;
u8
heads
,
sectors
;
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
"
);
return
1
;
}
if
(
pc
->
buf
[
3
]
&
0x80
)
if
(
buf
[
3
]
&
0x80
)
drive
->
dev_flags
|=
IDE_DFLAG_WP
;
else
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
]);
sector_size
=
be16_to_cpup
((
__be16
*
)
&
pc
->
buf
[
8
+
6
]);
cyls
=
be16_to_cpup
((
__be16
*
)
&
pc
->
buf
[
8
+
8
]);
rpm
=
be16_to_cpup
((
__be16
*
)
&
pc
->
buf
[
8
+
28
]);
heads
=
pc
->
buf
[
8
+
4
];
sectors
=
pc
->
buf
[
8
+
5
];
transfer_rate
=
be16_to_cpup
((
__be16
*
)
&
buf
[
8
+
2
]);
sector_size
=
be16_to_cpup
((
__be16
*
)
&
buf
[
8
+
6
]);
cyls
=
be16_to_cpup
((
__be16
*
)
&
buf
[
8
+
8
]);
rpm
=
be16_to_cpup
((
__be16
*
)
&
buf
[
8
+
28
]);
heads
=
buf
[
8
+
4
];
sectors
=
buf
[
8
+
5
];
capacity
=
cyls
*
heads
*
sectors
*
sector_size
;
...
...
@@ -387,22 +384,19 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
drive
->
capacity64
=
0
;
ide_floppy_create_read_capacity_cmd
(
&
pc
);
pc
.
buf
=
&
pc_buf
[
0
];
pc
.
buf_size
=
sizeof
(
pc_buf
);
if
(
ide_queue_pc_tail
(
drive
,
disk
,
&
pc
))
{
if
(
ide_queue_pc_tail
(
drive
,
disk
,
&
pc
,
pc_buf
,
pc
.
req_xfer
))
{
printk
(
KERN_ERR
PFX
"Can't get floppy parameters
\n
"
);
return
1
;
}
header_len
=
pc
.
buf
[
3
];
cap_desc
=
&
pc
.
buf
[
4
];
header_len
=
pc
_
buf
[
3
];
cap_desc
=
&
pc
_
buf
[
4
];
desc_cnt
=
header_len
/
8
;
/* capacity descriptor of 8 bytes */
for
(
i
=
0
;
i
<
desc_cnt
;
i
++
)
{
unsigned
int
desc_start
=
4
+
i
*
8
;
blocks
=
be32_to_cpup
((
__be32
*
)
&
pc
.
buf
[
desc_start
]);
length
=
be16_to_cpup
((
__be16
*
)
&
pc
.
buf
[
desc_start
+
6
]);
blocks
=
be32_to_cpup
((
__be32
*
)
&
pc
_
buf
[
desc_start
]);
length
=
be16_to_cpup
((
__be16
*
)
&
pc
_
buf
[
desc_start
+
6
]);
ide_debug_log
(
IDE_DBG_PROBE
,
"Descriptor %d: %dkB, %d blocks, "
"%d sector size"
,
...
...
@@ -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
*/
switch
(
pc
.
buf
[
desc_start
+
4
]
&
0x03
)
{
switch
(
pc
_
buf
[
desc_start
+
4
]
&
0x03
)
{
/* Clik! drive returns this instead of CAPACITY_CURRENT */
case
CAPACITY_UNFORMATTED
:
if
(
!
(
drive
->
atapi_flags
&
IDE_AFLAG_CLIK_DRIVE
))
...
...
@@ -464,7 +458,7 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
break
;
}
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 */
...
...
drivers/ide/ide-floppy_ioctl.c
View file @
8dcce408
...
...
@@ -47,15 +47,13 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive,
return
-
EINVAL
;
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
"
);
return
-
EIO
;
}
header_len
=
pc
->
buf
[
3
];
header_len
=
pc
_
buf
[
3
];
desc_cnt
=
header_len
/
8
;
/* capacity descriptor of 8 bytes */
u_index
=
0
;
...
...
@@ -72,8 +70,8 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive,
if
(
u_index
>=
u_array_size
)
break
;
/* User-supplied buffer too small */
blocks
=
be32_to_cpup
((
__be32
*
)
&
pc
->
buf
[
desc_start
]);
length
=
be16_to_cpup
((
__be16
*
)
&
pc
->
buf
[
desc_start
+
6
]);
blocks
=
be32_to_cpup
((
__be32
*
)
&
pc
_
buf
[
desc_start
]);
length
=
be16_to_cpup
((
__be16
*
)
&
pc
_
buf
[
desc_start
+
6
]);
if
(
put_user
(
blocks
,
argp
))
return
-
EFAULT
;
...
...
@@ -94,40 +92,42 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive,
return
0
;
}
static
void
ide_floppy_create_format_unit_cmd
(
struct
ide_atapi_pc
*
pc
,
int
b
,
int
l
,
int
flags
)
static
void
ide_floppy_create_format_unit_cmd
(
struct
ide_atapi_pc
*
pc
,
u8
*
buf
,
int
b
,
int
l
,
int
flags
)
{
ide_init_pc
(
pc
);
pc
->
c
[
0
]
=
GPCMD_FORMAT_UNIT
;
pc
->
c
[
1
]
=
0x17
;
memset
(
pc
->
buf
,
0
,
12
);
pc
->
buf
[
1
]
=
0xA2
;
memset
(
buf
,
0
,
12
);
buf
[
1
]
=
0xA2
;
/* Default format list header, u8 1: FOV/DCRT/IMM bits set */
if
(
flags
&
1
)
/* Verify bit on... */
pc
->
buf
[
1
]
^=
0x20
;
/* ... turn off DCRT bit */
pc
->
buf
[
3
]
=
8
;
buf
[
1
]
^=
0x20
;
/* ... turn off DCRT bit */
buf
[
3
]
=
8
;
put_unaligned
(
cpu_to_be32
(
b
),
(
unsigned
int
*
)(
&
pc
->
buf
[
4
]));
put_unaligned
(
cpu_to_be32
(
l
),
(
unsigned
int
*
)(
&
pc
->
buf
[
8
]));
pc
->
buf_size
=
12
;
put_unaligned
(
cpu_to_be32
(
b
),
(
unsigned
int
*
)(
&
buf
[
4
]));
put_unaligned
(
cpu_to_be32
(
l
),
(
unsigned
int
*
)(
&
buf
[
8
]));
pc
->
req_xfer
=
12
;
pc
->
flags
|=
PC_FLAG_WRITING
;
}
static
int
ide_floppy_get_sfrp_bit
(
ide_drive_t
*
drive
,
struct
ide_atapi_pc
*
pc
)
{
struct
ide_disk_obj
*
floppy
=
drive
->
driver_data
;
u8
buf
[
20
];
drive
->
atapi_flags
&=
~
IDE_AFLAG_SRFP
;
ide_floppy_create_mode_sense_cmd
(
pc
,
IDEFLOPPY_CAPABILITIES_PAGE
);
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
;
if
(
pc
->
buf
[
8
+
2
]
&
0x40
)
if
(
buf
[
8
+
2
]
&
0x40
)
drive
->
atapi_flags
|=
IDE_AFLAG_SRFP
;
return
0
;
...
...
@@ -137,6 +137,7 @@ static int ide_floppy_format_unit(ide_drive_t *drive, struct ide_atapi_pc *pc,
int
__user
*
arg
)
{
struct
ide_disk_obj
*
floppy
=
drive
->
driver_data
;
u8
buf
[
12
];
int
blocks
,
length
,
flags
,
err
=
0
;
if
(
floppy
->
openers
>
1
)
{
...
...
@@ -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_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
;
out:
...
...
@@ -196,11 +197,13 @@ static int ide_floppy_get_format_progress(ide_drive_t *drive,
int
__user
*
arg
)
{
struct
ide_disk_obj
*
floppy
=
drive
->
driver_data
;
u8
sense_buf
[
18
];
int
progress_indication
=
0x10000
;
if
(
drive
->
atapi_flags
&
IDE_AFLAG_SRFP
)
{
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
;
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)
* called on each failed packet command retry to analyze the request sense. We
* 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
;
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
->
asc
=
sense
[
12
];
...
...
@@ -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
"
,
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
)
pc
->
xferred
=
pc
->
req_xfer
-
tape
->
blk_size
*
get_unaligned_be32
(
&
sense
[
3
]);
rq
->
resid_len
=
tape
->
blk_size
*
get_unaligned_be32
(
&
sense
[
3
]);
/*
* 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)
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
;
}
}
...
...
@@ -354,12 +354,13 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc)
if
(
pc
->
c
[
0
]
==
REQUEST_SENSE
)
{
if
(
uptodate
)
idetape_analyze_error
(
drive
,
pc
->
buf
);
idetape_analyze_error
(
drive
);
else
printk
(
KERN_ERR
"ide-tape: Error in REQUEST SENSE "
"itself - Aborting request!
\n
"
);
}
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
;
...
...
@@ -371,38 +372,12 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc)
}
tape
->
first_frame
+=
blocks
;
rq
->
resid_len
-=
blocks
*
tape
->
blk_size
;
if
(
pc
->
error
)
{
uptodate
=
0
;
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
;
return
uptodate
;
...
...
@@ -477,6 +452,7 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive,
struct
ide_atapi_pc
*
pc
)
{
idetape_tape_t
*
tape
=
drive
->
driver_data
;
struct
request
*
rq
=
drive
->
hwif
->
rq
;
if
(
drive
->
failed_pc
==
NULL
&&
pc
->
c
[
0
]
!=
REQUEST_SENSE
)
drive
->
failed_pc
=
pc
;
...
...
@@ -486,7 +462,6 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive,
if
(
pc
->
retries
>
IDETAPE_MAX_PC_RETRIES
||
(
pc
->
flags
&
PC_FLAG_ABORT
))
{
unsigned
int
done
=
blk_rq_bytes
(
drive
->
hwif
->
rq
);
/*
* 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,
drive
->
failed_pc
=
NULL
;
drive
->
pc_callback
(
drive
,
0
);
ide_complete_rq
(
drive
,
-
EIO
,
done
);
ide_complete_rq
(
drive
,
-
EIO
,
blk_rq_bytes
(
rq
)
);
return
ide_stopped
;
}
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,
struct
ide_atapi_pc
*
pc
,
struct
request
*
rq
,
u8
opcode
)
{
unsigned
int
length
=
blk_rq_sectors
(
rq
);
unsigned
int
length
=
blk_rq_sectors
(
rq
)
/
(
tape
->
blk_size
>>
9
)
;
ide_init_pc
(
pc
);
put_unaligned
(
cpu_to_be32
(
length
),
(
unsigned
int
*
)
&
pc
->
c
[
1
]);
pc
->
c
[
1
]
=
1
;
pc
->
buf
=
NULL
;
pc
->
buf_size
=
length
*
tape
->
blk_size
;
pc
->
req_xfer
=
pc
->
buf_size
;
if
(
pc
->
req_xfer
==
tape
->
buffer_size
)
if
(
blk_rq_bytes
(
rq
)
==
tape
->
buffer_size
)
pc
->
flags
|=
PC_FLAG_DMA_OK
;
if
(
opcode
==
READ_6
)
...
...
@@ -713,7 +686,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
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
);
return
ide_tape_issue_pc
(
drive
,
&
cmd
,
pc
);
...
...
@@ -767,33 +740,53 @@ static int idetape_flush_tape_buffers(ide_drive_t *drive)
int
rc
;
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
)
return
rc
;
idetape_wait_ready
(
drive
,
60
*
5
*
HZ
);
return
0
;
}
static
void
idetape_create_read_position_cmd
(
struct
ide_atapi_pc
*
pc
)
{
ide_init_pc
(
pc
);
pc
->
c
[
0
]
=
READ_POSITION
;
pc
->
req_xfer
=
20
;
}
static
int
idetape_read_position
(
ide_drive_t
*
drive
)
static
int
ide_tape_read_position
(
ide_drive_t
*
drive
)
{
idetape_tape_t
*
tape
=
drive
->
driver_data
;
struct
ide_atapi_pc
pc
;
int
position
;
u8
buf
[
20
]
;
debug_log
(
DBG_PROCS
,
"Enter %s
\n
"
,
__func__
);
idetape_create_read_position_cmd
(
&
pc
);
if
(
ide_queue_pc_tail
(
drive
,
tape
->
disk
,
&
pc
))
/* prep cmd */
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
;
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
;
position
=
tape
->
first_frame
;
return
position
;
}
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
,
...
...
@@ -836,19 +829,21 @@ static int idetape_position_tape(ide_drive_t *drive, unsigned int block,
{
idetape_tape_t
*
tape
=
drive
->
driver_data
;
struct
gendisk
*
disk
=
tape
->
disk
;
int
ret
val
;
int
ret
;
struct
ide_atapi_pc
pc
;
if
(
tape
->
chrdev_dir
==
IDETAPE_DIR_READ
)
__ide_tape_discard_merge_buffer
(
drive
);
idetape_wait_ready
(
drive
,
60
*
5
*
HZ
);
idetape_create_locate_cmd
(
drive
,
&
pc
,
block
,
partition
,
skip
);
ret
val
=
ide_queue_pc_tail
(
drive
,
disk
,
&
pc
);
if
(
ret
val
)
return
(
retval
)
;
ret
=
ide_queue_pc_tail
(
drive
,
disk
,
&
pc
,
NULL
,
0
);
if
(
ret
)
return
ret
;
idetape_create_read_position_cmd
(
&
pc
);
return
ide_queue_pc_tail
(
drive
,
disk
,
&
pc
);
ret
=
ide_tape_read_position
(
drive
);
if
(
ret
<
0
)
return
ret
;
return
0
;
}
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
);
if
(
restore_position
)
{
position
=
idetape_read_position
(
drive
);
position
=
ide
_
tape_read_position
(
drive
);
seek
=
position
>
0
?
position
:
0
;
if
(
idetape_position_tape
(
drive
,
seek
,
0
,
0
))
{
printk
(
KERN_INFO
"ide-tape: %s: position_tape failed in"
...
...
@@ -1039,20 +1034,19 @@ static int idetape_rewind_tape(ide_drive_t *drive)
{
struct
ide_tape_obj
*
tape
=
drive
->
driver_data
;
struct
gendisk
*
disk
=
tape
->
disk
;
int
retval
;
struct
ide_atapi_pc
pc
;
int
ret
;
debug_log
(
DBG_SENSE
,
"Enter %s
\n
"
,
__func__
);
idetape_create_rewind_cmd
(
drive
,
&
pc
);
ret
val
=
ide_queue_pc_tail
(
drive
,
disk
,
&
pc
);
if
(
ret
val
)
return
ret
val
;
ret
=
ide_queue_pc_tail
(
drive
,
disk
,
&
pc
,
NULL
,
0
);
if
(
ret
)
return
ret
;
idetape_create_read_position_cmd
(
&
pc
);
retval
=
ide_queue_pc_tail
(
drive
,
disk
,
&
pc
);
if
(
retval
)
return
retval
;
ret
=
ide_tape_read_position
(
drive
);
if
(
ret
<
0
)
return
ret
;
return
0
;
}
...
...
@@ -1119,7 +1113,7 @@ static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op,
case
MTBSF
:
idetape_create_space_cmd
(
&
pc
,
mt_count
-
count
,
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
MTBSFM
:
if
(
!
sprev
)
...
...
@@ -1259,7 +1253,7 @@ static int idetape_write_filemark(ide_drive_t *drive)
/* Write a filemark */
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
"
);
return
-
EIO
;
}
...
...
@@ -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
);
case
MTEOM
:
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
:
(
void
)
idetape_rewind_tape
(
drive
);
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
:
if
(
mt_count
)
{
if
(
mt_count
<
tape
->
blk_size
||
...
...
@@ -1415,7 +1409,7 @@ static int idetape_chrdev_ioctl(struct inode *inode, struct file *file,
if
(
cmd
==
MTIOCGET
||
cmd
==
MTIOCPOS
)
{
block_offset
=
tape
->
valid
/
(
tape
->
blk_size
*
tape
->
user_bs_factor
);
position
=
idetape_read_position
(
drive
);
position
=
ide
_
tape_read_position
(
drive
);
if
(
position
<
0
)
return
-
EIO
;
}
...
...
@@ -1458,9 +1452,10 @@ static void ide_tape_get_bsize_from_bdesc(ide_drive_t *drive)
{
idetape_tape_t
*
tape
=
drive
->
driver_data
;
struct
ide_atapi_pc
pc
;
u8
buf
[
12
];
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
"
);
if
(
tape
->
blk_size
==
0
)
{
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)
}
return
;
}
tape
->
blk_size
=
(
pc
.
buf
[
4
+
5
]
<<
16
)
+
(
pc
.
buf
[
4
+
6
]
<<
8
)
+
pc
.
buf
[
4
+
7
];
tape
->
drv_write_prot
=
(
pc
.
buf
[
2
]
&
0x80
)
>>
7
;
tape
->
blk_size
=
(
buf
[
4
+
5
]
<<
16
)
+
(
buf
[
4
+
6
]
<<
8
)
+
buf
[
4
+
7
];
tape
->
drv_write_prot
=
(
buf
[
2
]
&
0x80
)
>>
7
;
}
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)
char
fw_rev
[
4
],
vendor_id
[
8
],
product_id
[
16
];
idetape_create_inquiry_cmd
(
&
pc
);
pc
.
buf
=
&
pc_buf
[
0
];
pc
.
buf_size
=
sizeof
(
pc_buf
);
if
(
ide_queue_pc_tail
(
drive
,
tape
->
disk
,
&
pc
))
{
if
(
ide_queue_pc_tail
(
drive
,
tape
->
disk
,
&
pc
,
pc_buf
,
pc
.
req_xfer
))
{
printk
(
KERN_ERR
"ide-tape: %s: can't get INQUIRY results
\n
"
,
tape
->
name
);
return
;
}
memcpy
(
vendor_id
,
&
pc
.
buf
[
8
],
8
);
memcpy
(
product_id
,
&
pc
.
buf
[
16
],
16
);
memcpy
(
fw_rev
,
&
pc
.
buf
[
32
],
4
);
memcpy
(
vendor_id
,
&
pc
_
buf
[
8
],
8
);
memcpy
(
product_id
,
&
pc
_
buf
[
16
],
16
);
memcpy
(
fw_rev
,
&
pc
_
buf
[
32
],
4
);
ide_fixstring
(
vendor_id
,
8
,
0
);
ide_fixstring
(
product_id
,
16
,
0
);
...
...
@@ -1643,11 +1635,11 @@ static void idetape_get_mode_sense_results(ide_drive_t *drive)
{
idetape_tape_t
*
tape
=
drive
->
driver_data
;
struct
ide_atapi_pc
pc
;
u8
*
caps
;
u8
buf
[
24
],
*
caps
;
u8
speed
,
max_speed
;
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"
" some default values
\n
"
);
tape
->
blk_size
=
512
;
...
...
@@ -1656,7 +1648,7 @@ static void idetape_get_mode_sense_results(ide_drive_t *drive)
put_unaligned
(
6
*
52
,
(
u16
*
)
&
tape
->
caps
[
16
]);
return
;
}
caps
=
pc
.
buf
+
4
+
pc
.
buf
[
3
];
caps
=
buf
+
4
+
buf
[
3
];
/* convert to host order and save for later use */
speed
=
be16_to_cpup
((
__be16
*
)
&
caps
[
14
]);
...
...
include/linux/ide.h
View file @
8dcce408
...
...
@@ -331,11 +331,6 @@ enum {
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)
struct
ide_atapi_pc
{
...
...
@@ -347,12 +342,6 @@ struct ide_atapi_pc {
/* bytes to transfer */
int
req_xfer
;
/* bytes actually transferred */
int
xferred
;
/* data buffer */
u8
*
buf
;
int
buf_size
;
/* the corresponding request */
struct
request
*
rq
;
...
...
@@ -363,8 +352,6 @@ struct ide_atapi_pc {
* those are more or less driver-specific and some of them are subject
* to change/removal later.
*/
u8
pc_buf
[
IDE_PC_BUFFER_SIZE
];
unsigned
long
timeout
;
};
...
...
@@ -1130,6 +1117,8 @@ void SELECT_MASK(ide_drive_t *, int);
u8
ide_read_error
(
ide_drive_t
*
);
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
*
);
void
ide_init_pc
(
struct
ide_atapi_pc
*
);
...
...
@@ -1154,7 +1143,8 @@ enum {
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_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