Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
8dcce408
cloud-kernel
项目概览
openanolis
/
cloud-kernel
大约 1 年 前同步成功
通知
158
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
8dcce408
编写于
6月 13, 2009
作者:
B
Bartlomiej Zolnierkiewicz
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'bp-remove-pc-buf' into for-next
Conflicts: drivers/ide/ide-tape.c
上级
f3ad1165
103f7033
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
230 addition
and
261 deletion
+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
未找到文件。
drivers/ide/ide-atapi.c
浏览文件 @
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__
);
if
(
ide_check_ireason
(
drive
,
rq
,
bcount
,
ireason
,
write
))
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
);
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
;
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
,
...
...
@@ -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
浏览文件 @
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
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录