// DECLARE_WAIT_QUEUE_HEAD(wq_head);
// DECLARE_WAIT_QUEUE(wait, current);
// add_wait_queue(&wq_head, &wait);
- ide_pci_controller.task = current;
+ // ide_pci_controller.task = current;
outb(0x00, REG_CTL(dev));
outb(0x00 | ((dev & 0x01) << 4), REG_DEVICE(dev)); // 根据文档P113,这里不用指定bit5, bit7,直接指示DRIVE就行
unsigned long flags;
irq_save(flags);
- current->state = TASK_WAIT;
outb(ATA_CMD_IDENTIFY, REG_CMD(dev));
+ wait_on_ide();
irq_restore(flags);
- schedule();
-
- // del_wait_queue(&wq_head, &wait);
-
insw(REG_DATA(dev), identify, SECT_SIZE / sizeof(u16));
// 第49个word的第8个bit位表示是否支持DMA
DECLARE_WAIT_QUEUE_HEAD(ide_wait_queue_head);
void sleep_on_ide() { sleep_on(&ide_wait_queue_head); }
+void wait_on_ide() { wait_event(&ide_wait_queue_head, ide_pci_controller.done); }
extern void *mbr_buf;
uint8_t ata_pci_bus_status();
}
#endif
- // wake_up(&ide_wait_queue_head);
+ ide_pci_controller.done = 1;
- ide_pci_controller.task->state = TASK_RUNNING;
+ wake_up(&ide_wait_queue_head);
+
+ // ide_pci_controller.task->state = TASK_RUNNING;
}
void ide_init() {
// memset((void *)&drv, 0, sizeof(drv));
+ memset(&ide_pci_controller, 0, sizeof(ide_pci_controller));
request_irq(0x0E, ide_irq_handler, "hard", "IDE");
// 这里应该改成一个请求链表
// 先简单实现
task_union *task;
+ int done;
} ide_pci_controller_t;
-void sleep_on_ide();
\ No newline at end of file
+void sleep_on_ide();
+void wait_on_ide();
\ No newline at end of file
void sleep_on(wait_queue_head_t *head);
void wake_up(wait_queue_head_t *head);
-#define __wait_event(head, condition) \
- do { \
- DECLARE_WAIT_QUEUE(__wait, current); \
- while (1) { \
- __do_wait(head, wa, TASK_WAIT); \
- if ((condition)) { \
- break; \
- } \
- schedule(); \
- } \
- __end_wait(head, &__wait); \
+unsigned long schedule();
+#define __wait_event(head, condition) \
+ do { \
+ DECLARE_WAIT_QUEUE(__wait, current); \
+ while (1) { \
+ __do_wait(head, &__wait, TASK_WAIT); \
+ if ((condition)) { \
+ break; \
+ } \
+ schedule(); \
+ } \
+ __end_wait(head, &__wait); \
} while (0)
#define wait_event(head, condition) \
*/
#include <sched.h>
+#include <wait.h>
+#if 0
+
+typedef enum {
+ DISK_REQ_IDENTIFY,
+ DISK_REQ_READ,
+} disk_request_cmd_t;
+
+typedef struct disk_request {
+ uint64_t pos; // 扇区号
+ uint16_t count; // 扇区数
+ void *buf; // 到的缓冲区
+ disk_request_cmd_t command; // 命令
+ wait_queue_head_t wait; // 等待队列
+ // 驱动器完全有可能在进程在进程睡眠到等待队列前返回数据并执行唤醒操作
+ // 这时等待队列上无进程,就相当于不执行任何操作
+ // 然后进程再睡眠到等待队列上,就会造成永远无法唤醒该进程
+ // 因此要添加一个字段,标志驱动器已经对该请求做过唤醒操作
+ // 进程在睡眠前需要检查该字段
+ int done;
+} disk_request_t;
+
+void send_disk_request() {
+ disk_request_t r;
+ r.pos = 0;
+ r.count = 1;
+ r.buf = kmalloc(512, 0);
+ r.command = DISK_REQ_IDENTIFY;
+ INIT_LIST_HEAD(&r.wait.task_list);
+ r.done = 0;
+
+ list_add_tail(&wq->task_list, &head->task_list);
+
+ // 发送命令
+ //....
+
+ unsigned long flags;
+ irq_save(flags);
+ if (0 == r.done) { // 驱动器还没完成
+ set_current_state(TASK_WAIT);
+ irq_restore(flags);
+ // 就算在schedule前驱动器触发中断也没有问题
+ // 因为该进程已经加到等待队列上了
+ // 所以它一定以唤醒该进程
+ schedule();
+ } else { // 驱动器已经完成
+ irq_restore(flags);
+ }
+}
+#endif
void disk_task_entry() {
while (1) {
- // TODO
- asm("hlt;");
- //schedule();
+ // TODO
+ asm("hlt;");
+ // schedule();
}
}