Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
d7b44dbc
提交
d7b44dbc
8月 24, 2007
创建
作者:
rsc
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
minor cleanups
上级
cb30c818
隐藏空白字符变更
内嵌
并排
正在显示
1 个修改的文件
包含
62 行增加
和
68 行删除
+62
-68
ide.c
ide.c
+62
-68
没有找到文件。
ide.c
浏览文件 @
d7b44dbc
...
@@ -26,20 +26,16 @@ static struct spinlock ide_lock;
...
@@ -26,20 +26,16 @@ static struct spinlock ide_lock;
static
struct
buf
*
ide_queue
;
static
struct
buf
*
ide_queue
;
static
int
disk_1_present
;
static
int
disk_1_present
;
static
int
ide_probe_disk1
(
void
);
static
void
ide_start_request
();
static
void
ide_start_request
();
//PAGEBREAK: 10
// Wait for IDE disk to become ready.
// Wait for IDE disk to become ready.
static
int
static
int
ide_wait_ready
(
int
check_error
)
ide_wait_ready
(
int
check_error
)
{
{
int
r
;
int
r
;
while
(((
r
=
inb
(
0x1
F7
))
&
(
IDE_BSY
|
IDE_DRDY
))
!=
IDE_DRDY
)
while
(((
r
=
inb
(
0x1
f7
))
&
IDE_BSY
)
||
!
(
r
&
IDE_DRDY
)
)
;
;
if
(
check_error
&&
(
r
&
(
IDE_DF
|
IDE_ERR
))
!=
0
)
if
(
check_error
&&
(
r
&
(
IDE_DF
|
IDE_ERR
))
!=
0
)
return
-
1
;
return
-
1
;
return
0
;
return
0
;
...
@@ -48,105 +44,103 @@ ide_wait_ready(int check_error)
...
@@ -48,105 +44,103 @@ ide_wait_ready(int check_error)
void
void
ide_init
(
void
)
ide_init
(
void
)
{
{
int
i
;
initlock
(
&
ide_lock
,
"ide"
);
initlock
(
&
ide_lock
,
"ide"
);
irq_enable
(
IRQ_IDE
);
irq_enable
(
IRQ_IDE
);
ioapic_enable
(
IRQ_IDE
,
ncpu
-
1
);
ioapic_enable
(
IRQ_IDE
,
ncpu
-
1
);
ide_wait_ready
(
0
);
ide_wait_ready
(
0
);
disk_1_present
=
ide_probe_disk1
();
// Check if disk 1 is present
outb
(
0x1f6
,
0xE0
|
(
1
<<
4
));
for
(
i
=
0
;
i
<
1000
;
i
++
){
if
(
inb
(
0x1f7
)
!=
0
){
disk_1_present
=
1
;
break
;
}
}
// Switch back to disk 0.
outb
(
0x1f6
,
0xE0
|
(
0
<<
4
));
}
}
//
Probe to see if disk 1 exists (we assume disk 0 exists)
.
//
Start the request for b. Caller must hold ide_lock
.
static
int
static
void
ide_
probe_disk1
(
void
)
ide_
start_request
(
struct
buf
*
b
)
{
{
int
r
,
x
;
if
(
b
==
0
)
panic
(
"ide_start_request"
);
// wait for Device 0 to be ready
ide_wait_ready
(
0
);
ide_wait_ready
(
0
);
outb
(
0x3f6
,
0
);
// generate interrupt
// switch to Device 1
outb
(
0x1f2
,
1
);
// number of sectors
outb
(
0x1
F6
,
0xE0
|
(
1
<<
4
)
);
outb
(
0x1
f3
,
b
->
sector
&
0xff
);
outb
(
0x1f4
,
(
b
->
sector
>>
8
)
&
0xff
);
// check for Device 1 to be ready for a while
outb
(
0x1f5
,
(
b
->
sector
>>
16
)
&
0xff
);
for
(
x
=
0
;
x
<
1000
&&
(
r
=
inb
(
0x1F7
))
==
0
;
x
++
)
outb
(
0x1f6
,
0xE0
|
((
b
->
dev
&
1
)
<<
4
)
|
((
b
->
sector
>>
24
)
&
0x0f
));
;
if
(
b
->
flags
&
B_WRITE
){
outb
(
0x1f7
,
IDE_CMD_WRITE
);
// switch back to Device 0
outsl
(
0x1f0
,
b
->
data
,
512
/
4
);
outb
(
0x1F6
,
0xE0
|
(
0
<<
4
));
}
else
{
outb
(
0x1f7
,
IDE_CMD_READ
);
return
x
<
1000
;
}
}
}
// Interrupt handler
- wake up the request that just finished
.
// Interrupt handler.
void
void
ide_intr
(
void
)
ide_intr
(
void
)
{
{
struct
buf
*
b
;
acquire
(
&
ide_lock
);
acquire
(
&
ide_lock
);
if
(
ide_queue
){
if
((
b
=
ide_queue
)
==
0
){
if
((
ide_queue
->
flags
&
B_WRITE
)
==
0
)
if
(
ide_wait_ready
(
1
)
>=
0
)
insl
(
0x1F0
,
ide_queue
->
data
,
512
/
4
);
ide_queue
->
done
=
1
;
wakeup
(
ide_queue
);
ide_queue
=
ide_queue
->
qnext
;
ide_start_request
();
}
else
{
cprintf
(
"stray ide interrupt
\n
"
);
cprintf
(
"stray ide interrupt
\n
"
);
release
(
&
ide_lock
);
return
;
}
}
release
(
&
ide_lock
);
}
// Start the next request in the queue.
// Read data if needed.
// Caller must hold ide_lock.
if
((
b
->
flags
&
B_WRITE
)
==
0
&&
ide_wait_ready
(
1
)
>=
0
)
static
void
insl
(
0x1f0
,
b
->
data
,
512
/
4
);
ide_start_request
(
void
)
{
// Wake process waiting for this buf.
if
(
ide_queue
){
b
->
done
=
1
;
ide_wait_ready
(
0
);
wakeup
(
b
);
outb
(
0x3f6
,
0
);
// generate interrupt
outb
(
0x1F2
,
1
);
// number of sectors
// Start disk on next buf in queue.
outb
(
0x1F3
,
ide_queue
->
sector
&
0xFF
);
if
((
ide_queue
=
b
->
qnext
)
!=
0
)
outb
(
0x1F4
,
(
ide_queue
->
sector
>>
8
)
&
0xFF
);
ide_start_request
(
ide_queue
);
outb
(
0x1F5
,
(
ide_queue
->
sector
>>
16
)
&
0xFF
);
outb
(
0x1F6
,
0xE0
|
release
(
&
ide_lock
);
((
ide_queue
->
dev
&
1
)
<<
4
)
|
((
ide_queue
->
sector
>>
24
)
&
0x0F
));
if
(
ide_queue
->
flags
&
B_WRITE
){
outb
(
0x1F7
,
IDE_CMD_WRITE
);
outsl
(
0x1F0
,
ide_queue
->
data
,
512
/
4
);
}
else
{
outb
(
0x1F7
,
IDE_CMD_READ
);
}
}
}
}
//PAGEBREAK: 30
//PAGEBREAK!
// Queue up a disk operation and wait for it to finish.
// Queue a disk operation and wait for it to finish.
// b must have B_BUSY set.
void
void
ide_rw
(
struct
buf
*
b
)
ide_rw
(
struct
buf
*
b
)
{
{
struct
buf
**
pp
;
struct
buf
**
pp
;
if
((
b
->
dev
&
0xff
)
&&
!
disk_1_present
)
if
(
!
(
b
->
flags
&
B_BUSY
))
panic
(
"ide_rw: buf not busy"
);
if
(
b
->
dev
!=
0
&&
!
disk_1_present
)
panic
(
"ide disk 1 not present"
);
panic
(
"ide disk 1 not present"
);
acquire
(
&
ide_lock
);
acquire
(
&
ide_lock
);
// Append b to ide_queue.
b
->
done
=
0
;
b
->
done
=
0
;
b
->
qnext
=
0
;
b
->
qnext
=
0
;
for
(
pp
=&
ide_queue
;
*
pp
;
pp
=&
(
*
pp
)
->
qnext
)
// append b to ide_queue
;
pp
=
&
ide_queue
;
while
(
*
pp
)
pp
=
&
(
*
pp
)
->
qnext
;
*
pp
=
b
;
*
pp
=
b
;
// Start disk if necessary.
if
(
ide_queue
==
b
)
if
(
ide_queue
==
b
)
ide_start_request
();
ide_start_request
(
b
);
// Wait for request to finish.
while
(
!
b
->
done
)
while
(
!
b
->
done
)
sleep
(
b
,
&
ide_lock
);
sleep
(
b
,
&
ide_lock
);
release
(
&
ide_lock
);
release
(
&
ide_lock
);
}
}
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论