]> Zhao Yanbai Git Server - kernel.git/commitdiff
ata pio 判断4个驱动器是否存在
authoracevest <zhaoyanbai@126.com>
Mon, 22 Nov 2021 03:47:05 +0000 (11:47 +0800)
committeracevest <zhaoyanbai@126.com>
Mon, 22 Nov 2021 03:47:05 +0000 (11:47 +0800)
drivers/ata.c
drivers/ata.h
drivers/ide.c
include/disk.h
kernel/setup.c
kernel/task_disk.c
kernel/wait.c

index 6296939231dfd5e44e5a0d08c0306514e4140a77..d07dfc2dba2d30ab95be8239fb92a9a39d7c0d06 100644 (file)
 
 extern ide_pci_controller_t ide_pci_controller;
 
+typedef struct _ide_drive {
+} ide_drive_t;
+
+#define MAX_IDE_DRIVE_CNT 4
+ide_drive_t ide_drives[MAX_IDE_DRIVE_CNT];
+
 #define ATA_TIMEOUT 10  // 10次时钟中断
 
 void ata_dma_read_ext(int dev, uint64_t pos, uint16_t count, void *dest);
@@ -47,14 +53,36 @@ void ata_send_read_identify_cmd(int dev) {}
 
 void ata_read_data(int dev, int sect_cnt, void *dst) { insl(REG_DATA(dev), dst, (512 * sect_cnt) / sizeof(uint32_t)); }
 
-void ata_read_identify(int dev) {
-    outb(0x00, REG_CTL(dev));
+void ata_read_identify(int dev, int enable_intr) {
+    uint8_t ctl = enable_intr ? 0x00 : ATA_CTL_NIEN;
+    printk("%x %x %x\n", REG_CTL(dev), REG_CTL(dev), 0x00 | ((dev & 0x01) << 4));
+    outb(ctl, REG_CTL(dev));
     outb(0x00 | ((dev & 0x01) << 4), REG_DEVICE(dev));  // 根据文档P113,这里不用指定bit5, bit7,直接指示DRIVE就行
     outb(ATA_CMD_IDENTIFY, REG_CMD(dev));
 }
 
+void ide_ata_init() {
+    for (int i = 0; i < MAX_IDE_DRIVE_CNT; i++) {
+        int dev = i;
+
+        ata_read_identify(dev, 0);
+
+        uint8_t status = inb(REG_STATUS(dev));
+        if (status == 0 || (status & ATA_STATUS_ERR) || (status & ATA_STATUS_RDY == 0)) {
+            printk("ata[%d] not exists: %x\n", i, status);
+            continue;
+        } else {
+            printk("ata[%d] exists: %x\n", i, status);
+            insl(REG_DATA(dev), identify, SECT_SIZE / sizeof(uint32_t));
+        }
+    }
+    asm("cli;hlt;");
+}
+
 void ata_init() {
     disk_request_t r;
+
+    r.dev = 0;
     r.buf = (void *)identify;
     r.count = 1;
     r.pos = 0;
@@ -80,18 +108,18 @@ void ata_init() {
     // TODO REMOVE
     mbr_buf = kmalloc(SECT_SIZE, 0);
     r.command = DISK_REQ_READ;
-    r.pos = 1;
+    r.pos = 0;
     r.count = 1;
     r.buf = mbr_buf;
     send_disk_request(&r);
 
-    uint16_t *p = (uint16_t *)mbr_buf;
-    for (int i = 0; i < 256; i++) {
-        if (i % 12 == 0) {
-            printk("\n[%03d] ", i * 2);
-        }
-        printk("%04x ", p[i]);
-    }
+    // uint16_t *p = (uint16_t *)mbr_buf;
+    // for (int i = 0; i < 256; i++) {
+    //     if (i % 12 == 0) {
+    //         printk("\n[%03d] ", i * 2);
+    //     }
+    //     printk("%04x ", p[i]);
+    // }
 }
 
 void ata_read_identify_old(int dev) {  // 这里所用的dev是逻辑编号 ATA0、ATA1下的Master、Salve的dev分别为0,1,2,3
index 904f3af0abaa8a2340a53f136918323f51dfd27d..e0f71d170f3d65f7f9d35f2777068d292af87ae6 100644 (file)
@@ -18,7 +18,7 @@ extern unsigned int ATA_CHL1_CMD_BASE;
 // bit7: HOB    High Order Byte (defined by 48-bit Address feature set).
 // bit[3-6]: -
 // bit2: SRST   Software Reset
-// bit1: IEN    Interrupt Enable
+// bit1: IEN    disable Interrupt
 // bit0: 0
 extern unsigned int ATA_CHL0_CTL_BASE;
 extern unsigned int ATA_CHL1_CTL_BASE;
@@ -95,8 +95,8 @@ extern unsigned int ATA_CHL1_CTL_BASE;
 #define ATA_CTL_SRST 0x04       /* soft reset controller */
 #define ATA_CTL_NIEN 0x02       /* disable interrupts */
 
-#define ATA_GET_CHL(dev) (0) /* only support channel 0 */
-#define ATA_GET_DEV(dev) (0) /* only support one hard disk */
+#define ATA_GET_CHL(dev) (((dev) >> 1) & 0x01)
+#define ATA_GET_DEV(dev) (((dev) >> 1) & 0x01)
 
 #define REG_CMD_BASE(dev, offset) (ATA_GET_CHL(dev) ? (ATA_CHL1_CMD_BASE + offset) : (ATA_CHL0_CMD_BASE + offset))
 #define REG_CTL_BASE(dev, offset) (ATA_GET_CHL(dev) ? (ATA_CHL1_CTL_BASE + offset) : (ATA_CHL0_CTL_BASE + offset))
index 64fcd09fdebc3b51fd650f3715ce60d63aa946c6..cc9f0f4e02a0d8c7f876937162c55295b2893ccc 100644 (file)
@@ -197,14 +197,16 @@ void ide_pci_init(pci_device_t *pci) {
 void init_pci_controller(unsigned int classcode) {
     pci_device_t *pci = pci_find_device_by_classcode(classcode);
     if (pci != 0 && pci->intr_line < 16) {
-        printk("found pci vendor %04x device %04x class %04x intr %d\n", pci->vendor, pci->device, pci->classcode,
-               pci->intr_line);
+        printk("found pci vendor %04x device %04x class %04x intr %d progif: %x\n", pci->vendor, pci->device,
+               pci->classcode, pci->intr_line, pci->progif);
         // printl(17, "found pci vendor %04x device %04x class %04x intr %d", pci->vendor, pci->device,
         // pci->classcode,
         // pci->intr_line);
         ide_pci_init(pci);
+        // while (1) asm("cli;hlt;");
     }
 }
+
 void ide_default_intr() {}
 // void ide_default_intr() {
 //     // printd("%s\n", __func__);
@@ -532,7 +534,7 @@ void ide_irq() { ide_intr_func(); }
 //     printk("%02x %02x\n", cl, ch);
 // }
 
-void ata_read_identify(int dev);
+// void ata_read_identify(int dev);
 
 DECLARE_WAIT_QUEUE_HEAD(ide_wait_queue_head);
 
@@ -546,9 +548,9 @@ uint8_t ata_pci_bus_status();
 extern ide_pci_controller_t ide_pci_controller;
 
 void ide_irq_handler(unsigned int irq, pt_regs_t *regs, void *devid) {
-    printk("ide irq handler %d \n", irq);
+    // printk("ide irq handler %d \n", irq);
 
-    printk("ide pci status after interrupt: %x\n", ata_pci_bus_status());
+    printk("ide irq %d handler pci status after interrupt: %x\n", irq, ata_pci_bus_status());
 
     ide_pci_controller.done = 1;
 
@@ -559,6 +561,9 @@ void ide_init() {
     // memset((void *)&drv, 0, sizeof(drv));
     memset(&ide_pci_controller, 0, sizeof(ide_pci_controller));
 
+    void ide_ata_init();
+    ide_ata_init();
+
     request_irq(0x0E, ide_irq_handler, "hard", "IDE");
 
     // init_pci_controller(0x0106);
index 0321bb53720cab1aebc8174c9cb9df08d49de3c8..96ef5739cca8af13527a201ca8031964e04d284c 100644 (file)
@@ -20,6 +20,7 @@ typedef enum {
 } disk_request_cmd_t;
 
 typedef struct disk_request {
+    int dev;
     uint64_t pos;                // 扇区号
     uint16_t count;              // 扇区数
     void *buf;                   // 到的缓冲区
index 87d984ccf36af03d98487343097d5f5226863ce5..2c29d1b88138ee3209235e926da25c0903a8c25e 100644 (file)
@@ -88,7 +88,7 @@ void setup_kernel() {
     printk(version);
 
     extern tty_t monitor_tty;
-    tty_switch(&monitor_tty);
+    // tty_switch(&monitor_tty);
 
     void ide_init();
     ide_init();
index f6d8f4c42c234ea2b93c41fa857e37e582e2edfd..b89631a20b7ab277998f88a7ead5fbe58cad2fcb 100644 (file)
@@ -21,7 +21,6 @@ void disk_init() {
     INIT_LIST_HEAD(&disk_request_queue.list);
 }
 
-#if 1
 void send_disk_request(disk_request_t *r) {
     if (NULL == r) {
         panic("null disk request");
@@ -56,25 +55,25 @@ void send_disk_request(disk_request_t *r) {
     irq_restore(flags);
 
     // 唤醒task_disk
-    printk("up sem\n");
+    // printk("up sem\n");
     up(&disk_request_queue.sem);
 
     // 等待task_dist结束
-    printk("wait event\n");
+    // printk("wait event\n");
     wait_event(&r->wait, r->done != 0);
 
-    printk("wait finished\n");
+    // printk("wait finished\n");
 }
-#endif
 
 void disk_task_entry() {
+    int r_cnt = 0;
     while (1) {
         void prepare_to_wait_on_ide();
         prepare_to_wait_on_ide();
 
-        printk("wait for new hard disk request\n");
+        // printk("wait for new hard disk request\n");
         down(&disk_request_queue.sem);
-        printk("hard disk request: %d\n", disk_request_queue.count++);
+        // printk("hard disk request: %d\n", disk_request_queue.count++);
 
         unsigned long flags;
         irq_save(flags);
@@ -87,7 +86,7 @@ void disk_task_entry() {
                 panic("no disk request");
             }
 
-            printk("disk request: pos %ld count %d cmd %d\n", r->pos, r->count, r->command);
+            printk("disk request[%d]: dev %d pos %ld count %d cmd %d\n", r_cnt++, r->dev, r->pos, r->count, r->command);
         }
 
         irq_restore(flags);
@@ -96,18 +95,17 @@ void disk_task_entry() {
             continue;
         }
 
-        int dev = 0;
         switch (r->command) {
         case DISK_REQ_IDENTIFY:
             assert(r->count == 1);
-            void ata_read_identify(int dev);
-            ata_read_identify(dev);
+            void ata_read_identify(int dev, int enable_intr);
+            ata_read_identify(r->dev, 1);
             break;
         case DISK_REQ_READ:
             assert(r->count > 0);
             assert(r->buf != NULL);
             void ata_dma_read_ext(int dev, uint64_t pos, uint16_t count, void *dest);
-            ata_dma_read_ext(dev, r->pos, r->count, r->buf);
+            ata_dma_read_ext(r->dev, r->pos, r->count, r->buf);
             break;
         default:
             break;
@@ -120,7 +118,7 @@ void disk_task_entry() {
         // 读数据
         if (DISK_REQ_IDENTIFY == r->command) {
             void ata_read_data(int dev, int sect_cnt, void *dst);
-            ata_read_data(dev, 1, r->buf);
+            ata_read_data(r->dev, 1, r->buf);
         }
 
         // 唤醒等待该请求的进程
index f671a39b7ef390527a8fde8cbfd129cd8ddea3d2..e6bdb4ee96c4b4b3410be5d2cfb7e8b93a6e56ed 100644 (file)
@@ -67,7 +67,7 @@ void __wake_up(wait_queue_head_t *head, int nr) {
     irq_save(flags);
     list_for_each_entry_safe(p, tmp, &head->task_list, task_list) {
         list_del(&p->task_list);
-        printk("wakeup: %s\n", p->task->name);
+        // printk("wakeup: %s\n", p->task->name);
         p->task->state = TASK_READY;
 
         --nr;